From 63f5ead209c3fa714ad943807060c5f17059cb45 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 17:35:59 +0800 Subject: [PATCH 01/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: Id66d3f55632fc4354cc9ea4d97ad10ceab644815 --- 3178.diff.txt | 1798 +++++++++++++++++ .../service/test/BUILD.gn | 89 + .../kv_store_nb_delegate_corruption_mock.cpp | 345 ++++ .../kv_store_nb_delegate_corruption_mock.h | 113 ++ .../test/mock/preprocess_utils_mock.cpp | 204 ++ .../service/test/mock/preprocess_utils_mock.h | 52 + .../test/udmf_db_corruption_mock_test.cpp | 388 ++++ .../service/test/udmf_run_time_store_test.cpp | 28 + .../service/test/udmf_service_impl_test.cpp | 34 + .../service/udmf/store/runtime_store.cpp | 66 +- .../service/udmf/store/runtime_store.h | 3 + .../service/udmf/store/store_cache.cpp | 15 +- .../service/udmf/store/store_cache.h | 1 + .../service/udmf/udmf_service_impl.cpp | 72 +- .../service/udmf/udmf_service_impl.h | 1 + 15 files changed, 3165 insertions(+), 44 deletions(-) create mode 100644 3178.diff.txt create mode 100644 services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp create mode 100644 services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h create mode 100644 services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp create mode 100644 services/distributeddataservice/service/test/mock/preprocess_utils_mock.h create mode 100644 services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp diff --git a/3178.diff.txt b/3178.diff.txt new file mode 100644 index 000000000..d941b6552 --- /dev/null +++ b/3178.diff.txt @@ -0,0 +1,1798 @@ +diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn +index c46be02227591b1f6b100bf30c6d7e901a3bb939..a4956c0691685940861d91b2951bf2173b8f9efd 100644 +--- a/services/distributeddataservice/service/test/BUILD.gn ++++ b/services/distributeddataservice/service/test/BUILD.gn +@@ -2105,6 +2105,94 @@ ohos_unittest("BackupManagerServiceTest") { + ] + } + ++ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { ++ module_out_path = module_output_path ++ sanitize = { ++ cfi = true ++ cfi_cross_dso = true ++ debug = false ++ blocklist = "${datamgr_service_path}/cfi_blocklist.txt" ++ } ++ sources = [ ++ "udmf_db_corruption_mock_test.cpp", ++ "mock/kv_store_nb_delegate_corruption_mock.cpp", ++ "mock/preprocess_utils_mock.cpp", ++ "${data_service_path}/service/udmf/udmf_service_impl.cpp", ++ "${data_service_path}/service/udmf/lifecycle/clean_on_startup.cpp", ++ "${data_service_path}/service/udmf/lifecycle/clean_on_timeout.cpp", ++ "${data_service_path}/service/udmf/lifecycle/lifecycle_manager.cpp", ++ "${data_service_path}/service/udmf/lifecycle/lifecycle_policy.cpp", ++ "${data_service_path}/service/udmf/permission/checker_manager.cpp", ++ "${data_service_path}/service/udmf/permission/data_checker.cpp", ++ "${data_service_path}/service/udmf/permission/uri_permission_manager.cpp", ++ "${data_service_path}/service/udmf/preprocess/data_handler.cpp", ++ "${data_service_path}/service/udmf/preprocess/udmf_notifier_proxy.cpp", ++ "${data_service_path}/service/udmf/store/runtime_store.cpp", ++ "${data_service_path}/service/udmf/store/store_account_observer.cpp", ++ "${data_service_path}/service/udmf/store/store_cache.cpp", ++ "${data_service_path}/service/udmf/udmf_service_stub.cpp", ++ "${data_service_path}/app/src/kvstore_meta_manager.cpp", ++ ] ++ ++ include_dirs = [ ++ "${data_service_path}/adapter/include/account", ++ "${data_service_path}/adapter/include/communicator", ++ "${data_service_path}/app/src", ++ "${data_service_path}/service/kvdb", ++ "${data_service_path}/service/matrix/include", ++ "${data_service_path}/service/udmf", ++ "${data_service_path}/service/udmf/store", ++ "${data_service_path}/service/udmf/preprocess", ++ "${data_service_path}/service/udmf/permission", ++ "${data_service_path}/service/test/mock", ++ ] ++ ++ configs = [ ":module_private_config" ] ++ ++ external_deps = [ ++ "ability_base:base", ++ "ability_base:zuri", ++ "ability_base:want", ++ "ability_runtime:uri_permission_mgr", ++ "access_token:libaccesstoken_sdk", ++ "access_token:libnativetoken_shared", ++ "access_token:libtoken_setproc", ++ "access_token:libtokenid_sdk", ++ "app_file_service:remote_file_share_native", ++ "bundle_framework:appexecfwk_base", ++ "bundle_framework:appexecfwk_core", ++ "device_manager:devicemanagersdk", ++ "dfs_service:distributed_file_daemon_kit_inner", ++ "hilog:libhilog", ++ "hisysevent:libhisysevent", ++ "hitrace:hitrace_meter", ++ "hitrace:libhitracechain", ++ "ipc:ipc_core", ++ "kv_store:distributeddata_inner", ++ "kv_store:distributeddb", ++ "kv_store:distributeddata_mgr", ++ "udmf:udmf_client", ++ "udmf:utd_client", ++ "dsoftbus:softbus_client", ++ "samgr:samgr_proxy", ++ "safwk:system_ability_fwk", ++ "openssl:libcrypto_shared", ++ "googletest:gmock_main", ++ "googletest:gtest_main", ++ "dataclassification:data_transit_mgr", ++ ] ++ ++ deps = [ ++ "${data_service_path}/framework:distributeddatasvcfwk", ++ "${data_service_path}/service:distributeddatasvc", ++ ] ++ ++ defines = [ ++ "private=public", ++ "protected=public", ++ ] ++} ++ + ############################################################################### + group("unittest") { + testonly = true +@@ -2133,6 +2221,7 @@ group("unittest") { + ":UdmfRunTimeStoreTest", + ":UdmfServiceImplMockTest", + ":UdmfServiceImplTest", ++ ":UdmfServiceImplDbCorruptionMockTest", + ":UdmfServiceStubMockTest", + ":UdmfServiceStubTest", + ] +diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp +new file mode 100644 +index 0000000000000000000000000000000000000000..04a12f2a08f1d7370388f9c7434bc28c3d4bdb37 +--- /dev/null ++++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp +@@ -0,0 +1,345 @@ ++/* ++ * Copyright (c) 2024 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 "kv_store_nb_delegate_corruption_mock.h" ++ ++#include "store_types.h" ++namespace DistributedDB { ++DBStatus KvStoreNbDelegateCorruptionMock::Get(const Key &key, Value &value) const ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, std::vector &entries) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, std::vector &entries) const ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, KvStoreResultSet *&resultSet) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetCount(const Query &query, int &count) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::CloseResultSet(KvStoreResultSet *&resultSet) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Put(const Key &key, const Value &value) ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::PutBatch(const std::vector &entries) ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::DeleteBatch(const std::vector &keys) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Delete(const Key &key) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetLocal(const Key &key, Value &value) const ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetLocalEntries(const Key &keyPrefix, std::vector &entries) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::PutLocal(const Key &key, const Value &value) ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocal(const Key &key) ++{ ++ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, ++ const KvStoreNbPublishOnConflict &onConflict) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::RegisterObserver(const Key &key, unsigned int mode, ++ KvStoreObserver *observer) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::UnRegisterObserver(const KvStoreObserver *observer) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device) ++{ ++ return DBStatus::OK; ++} ++ ++std::string KvStoreNbDelegateCorruptionMock::GetStoreId() const ++{ ++ return "ok"; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, ++ const std::function &devicesMap)> &onComplete, ++ bool wait) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Pragma(PragmaCmd cmd, PragmaData ¶mData) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetConflictNotifier(int conflictType, ++ const KvStoreNbConflictNotifier ¬ifier) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Rekey(const CipherPassword &password) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Export(const std::string &filePath, ++ const CipherPassword &passwd, bool force) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Import(const std::string &filePath, const CipherPassword &passwd, ++ bool isNeedIntegrityCheck) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::StartTransaction() ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Commit() ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Rollback() ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::PutLocalBatch(const std::vector &entries) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocalBatch(const std::vector &keys) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetSecurityOption(SecurityOption &option) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, ++ const std::function &devicesMap)> &onComplete, ++ const Query &query, bool wait) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::CheckIntegrity() const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetEqualIdentifier(const std::string &identifier, ++ const std::vector &targets) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetPushDataInterceptor(const PushDataInterceptor &interceptor) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SubscribeRemoteQuery(const std::vector &devices, ++ const std::function &devicesMap)> &onComplete, ++ const Query &query, bool wait) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::UnSubscribeRemoteQuery(const std::vector &devices, ++ const std::function &devicesMap)> &onComplete, ++ const Query &query, bool wait) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData() ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetKeys(const Key &keyPrefix, std::vector &keys) const ++{ ++ return DBStatus::OK; ++} ++ ++size_t KvStoreNbDelegateCorruptionMock::GetSyncDataSize(const std::string &device) const ++{ ++ size_t size = 0; ++ return size; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::UpdateKey(const UpdateKeyCallback &callback) ++{ ++ return DBStatus::OK; ++} ++ ++std::pair KvStoreNbDelegateCorruptionMock::GetWatermarkInfo(const std::string &device) ++{ ++ std::pair ret; ++ return ret; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDB(const std::map> &cloudDBs) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDbSchema(const std::map &schema) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, ClearMode mode) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) ++{ ++ return DBStatus::OK; ++} ++ ++int32_t KvStoreNbDelegateCorruptionMock::GetTaskCount() ++{ ++ int32_t taskCount = taskCountMock_; ++ return taskCount; ++} ++ ++void KvStoreNbDelegateCorruptionMock::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) ++{ ++ auto callback_ = callback; ++} ++ ++std::pair> KvStoreNbDelegateCorruptionMock::GetCloudVersion( ++ const std::string &device) ++{ ++ if (device.empty()) { ++ return { DBStatus::OK, {} }; ++ } else if (device == "test") { ++ return { DBStatus::DB_ERROR, {} }; ++ } else if (device == "device") { ++ return { DBStatus::DB_ERROR, {{device, device}} }; ++ } else { ++ return { DBStatus::OK, {{device, device}} }; ++ } ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::SetCloudSyncConfig(const CloudSyncConfig &config) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::GetDeviceEntries(const std::string &device, std::vector &entries) const ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) ++{ ++ return DBStatus::OK; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::CancelSync(uint32_t syncId) ++{ ++ return DBStatus::OK; ++} ++ ++KvStoreNbDelegate::DatabaseStatus KvStoreNbDelegateCorruptionMock::GetDatabaseStatus() const ++{ ++ return {}; ++} ++ ++DBStatus KvStoreNbDelegateCorruptionMock::ClearMetaData(ClearKvMetaDataOption option) ++{ ++ return DBStatus::OK; ++} ++} // namespace DistributedDB +\ No newline at end of file +diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h +new file mode 100644 +index 0000000000000000000000000000000000000000..16176d2a3f1d3ef9e4db2addc824136697bda937 +--- /dev/null ++++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (c) 2021 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 KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK ++#define KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK ++ ++#include ++#include ++#include ++ ++#include "cloud/cloud_store_types.h" ++#include "cloud/icloud_db.h" ++#include "intercepted_data.h" ++#include "iprocess_system_api_adapter.h" ++#include "kv_store_nb_conflict_data.h" ++#include "kv_store_nb_delegate.h" ++#include "kv_store_observer.h" ++#include "kv_store_result_set.h" ++#include "query.h" ++#include "store_types.h" ++ ++namespace DistributedDB { ++class KvStoreNbDelegateCorruptionMock : public DistributedDB::KvStoreNbDelegate { ++public: ++ int32_t taskCountMock_ = 0; ++ ~KvStoreNbDelegateCorruptionMock() = default; ++ DBStatus Get(const Key &key, Value &value) const; ++ DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const; ++ DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const; ++ DBStatus GetEntries(const Query &query, std::vector &entries) const; ++ DBStatus GetEntries(const Query &query, KvStoreResultSet *&resultSet) const; ++ DBStatus GetCount(const Query &query, int &count) const; ++ DBStatus CloseResultSet(KvStoreResultSet *&resultSet); ++ DBStatus Put(const Key &key, const Value &value); ++ DBStatus PutBatch(const std::vector &entries); ++ DBStatus DeleteBatch(const std::vector &keys); ++ DBStatus Delete(const Key &key); ++ DBStatus GetLocal(const Key &key, Value &value) const; ++ DBStatus GetLocalEntries(const Key &keyPrefix, std::vector &entries) const; ++ DBStatus PutLocal(const Key &key, const Value &value); ++ DBStatus DeleteLocal(const Key &key); ++ DBStatus PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, ++ const KvStoreNbPublishOnConflict &onConflict); ++ DBStatus UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp); ++ DBStatus RegisterObserver(const Key &key, unsigned int mode, KvStoreObserver *observer); ++ DBStatus UnRegisterObserver(const KvStoreObserver *observer); ++ DBStatus RemoveDeviceData(const std::string &device); ++ std::string GetStoreId() const; ++ DBStatus Sync(const std::vector &devices, SyncMode mode, ++ const std::function &devicesMap)> &onComplete, ++ bool wait = false); ++ DBStatus Pragma(PragmaCmd cmd, PragmaData ¶mData); ++ DBStatus SetConflictNotifier(int conflictType, ++ const KvStoreNbConflictNotifier ¬ifier); ++ DBStatus Rekey(const CipherPassword &password); ++ DBStatus Export(const std::string &filePath, const CipherPassword &passwd, bool force = false); ++ DBStatus Import(const std::string &filePath, const CipherPassword &passwd, bool isNeedIntegrityCheck = false); ++ DBStatus StartTransaction(); ++ DBStatus Commit(); ++ DBStatus Rollback(); ++ DBStatus PutLocalBatch(const std::vector &entries); ++ DBStatus DeleteLocalBatch(const std::vector &keys); ++ DBStatus GetSecurityOption(SecurityOption &option) const; ++ DBStatus SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier); ++ DBStatus Sync(const std::vector &devices, SyncMode mode, ++ const std::function &devicesMap)> &onComplete, ++ const Query &query, bool wait); ++ DBStatus CheckIntegrity() const; ++ DBStatus SetEqualIdentifier(const std::string &identifier, ++ const std::vector &targets); ++ DBStatus SetPushDataInterceptor(const PushDataInterceptor &interceptor); ++ DBStatus SubscribeRemoteQuery(const std::vector &devices, ++ const std::function &devicesMap)> &onComplete, ++ const Query &query, bool wait); ++ DBStatus UnSubscribeRemoteQuery(const std::vector &devices, ++ const std::function &devicesMap)> &onComplete, ++ const Query &query, bool wait); ++ DBStatus RemoveDeviceData(); ++ DBStatus GetKeys(const Key &keyPrefix, std::vector &keys) const; ++ size_t GetSyncDataSize(const std::string &device) const; ++ DBStatus UpdateKey(const UpdateKeyCallback &callback); ++ std::pair GetWatermarkInfo(const std::string &device); ++ DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess); ++ DBStatus SetCloudDB(const std::map> &cloudDBs); ++ DBStatus SetCloudDbSchema(const std::map &schema); ++ DBStatus RemoveDeviceData(const std::string &device, ClearMode mode); ++ DBStatus RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode); ++ int32_t GetTaskCount(); ++ void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback); ++ std::pair> GetCloudVersion( ++ const std::string &device); ++ DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor); ++ DBStatus SetCloudSyncConfig(const CloudSyncConfig &config); ++ DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const; ++ DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess); ++ DBStatus CancelSync(uint32_t syncId); ++ DatabaseStatus GetDatabaseStatus() const; ++ DBStatus ClearMetaData(ClearKvMetaDataOption option); ++}; ++} // namespace DistributedDB ++#endif // KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK +\ No newline at end of file +diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp +new file mode 100644 +index 0000000000000000000000000000000000000000..af03ce4d651ba2a21c1024a9b192d504a570dd8b +--- /dev/null ++++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp +@@ -0,0 +1,204 @@ ++/* ++ * 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. ++ */ ++#define LOG_TAG "PreProcessUtils" ++ ++#include "preprocess_utils.h" ++ ++#include "bundle_info.h" ++#include "dds_trace.h" ++#include "udmf_radar_reporter.h" ++#include "accesstoken_kit.h" ++#include "device_manager_adapter.h" ++#include "file_mount_manager.h" ++#include "iservice_registry.h" ++#include "log_print.h" ++#include "system_ability_definition.h" ++#include "udmf_radar_reporter.h" ++#include "udmf_utils.h" ++#include "utils/crypto.h" ++#include "uri_permission_manager_client.h" ++#include "ipc_skeleton.h" ++#include "bundle_mgr_interface.h" ++namespace OHOS { ++namespace UDMF { ++using namespace OHOS::DistributedDataDfx; ++using namespace Security::AccessToken; ++using namespace OHOS::AppFileService::ModuleRemoteFileShare; ++using namespace RadarReporter; ++ ++int32_t PreProcessUtils::FillRuntimeInfo(UnifiedData &data, CustomOption &option) ++{ ++ auto it = UD_INTENTION_MAP.find(option.intention); ++ if (it == UD_INTENTION_MAP.end()) { ++ return E_ERROR; ++ } ++ std::string bundleName = "bundleName"; ++ std::string intention = it->second; ++ UnifiedKey key(intention, bundleName, GenerateId()); ++ Privilege privilege; ++ privilege.tokenId = option.tokenId; ++ ++ Runtime runtime; ++ runtime.key = key; ++ runtime.privileges.emplace_back(privilege); ++ runtime.createTime = GetTimestamp(); ++ runtime.sourcePackage = bundleName; ++ runtime.createPackage = bundleName; ++ runtime.recordTotalNum = static_cast(data.GetRecords().size()); ++ runtime.tokenId = option.tokenId; ++ runtime.visibility = option.visibility; ++ runtime.appId = "appId"; ++ data.SetRuntime(runtime); ++ return E_OK; ++} ++ ++std::string PreProcessUtils::GenerateId() ++{ ++ return "1122ac"; ++} ++ ++time_t PreProcessUtils::GetTimestamp() ++{ ++ std::chrono::time_point tp = ++ std::chrono::time_point_cast(std::chrono::system_clock::now()); ++ time_t timestamp = tp.time_since_epoch().count(); ++ return timestamp; ++} ++ ++int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId, int &userId) ++{ ++ userId = 100; ++ return E_OK; ++} ++ ++bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName) ++{ ++ bundleName = "processName"; ++ return true; ++ ++} ++ ++bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName) ++{ ++ processName = "processName"; ++ return true; ++} ++ ++std::string PreProcessUtils::GetAppId(const std::string &bundleName) ++{ ++ return "com.demo.test"; ++} ++ ++std::string PreProcessUtils::GetLocalDeviceId() ++{ ++ return "123"; ++} ++ ++void PreProcessUtils::SetRemoteData(UnifiedData &data) ++{ ++ return; ++} ++ ++int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) ++{ ++ return E_OK; ++} ++ ++bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex) ++{ ++ return true; ++} ++ ++bool PreProcessUtils::IsNetworkingEnabled() ++{ ++ return true; ++} ++ ++void PreProcessUtils::ProcessFileType(std::vector> records, ++ std::function)> callback) ++{ ++ return; ++} ++ ++void PreProcessUtils::ProcessRecord(std::shared_ptr record, uint32_t tokenId, ++ bool isLocal, std::vector &uris) ++{ ++ return; ++} ++ ++void PreProcessUtils::GetHtmlFileUris(uint32_t tokenId, UnifiedData &data, ++ bool isLocal, std::vector &uris) ++{ ++ return; ++} ++ ++void PreProcessUtils::ClearHtmlDfsUris(UnifiedData &data) ++{ ++ return; ++} ++ ++void PreProcessUtils::ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris) ++{ ++ return; ++} ++ ++void PreProcessUtils::SetRecordUid(UnifiedData &data) ++{ ++ return; ++} ++ ++bool PreProcessUtils::GetDetailsFromUData(const UnifiedData &data, UDDetails &details) ++{ ++ return true; ++} ++ ++Status PreProcessUtils::GetSummaryFromDetails(const UDDetails &details, Summary &summary) ++{ ++ return E_OK; ++} ++ ++sptr PreProcessUtils::GetBundleMgr() ++{ ++ auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); ++ if (samgrProxy == nullptr) { ++ ZLOGE("Failed to get system ability mgr."); ++ return nullptr; ++ } ++ auto bundleMgrProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); ++ if (bundleMgrProxy == nullptr) { ++ ZLOGE("Failed to Get BMS SA."); ++ return nullptr; ++ } ++ auto bundleManager = iface_cast(bundleMgrProxy); ++ if (bundleManager == nullptr) { ++ ZLOGE("Failed to get bundle manager"); ++ return nullptr; ++ } ++ return bundleManager; ++} ++ ++bool PreProcessUtils::GetSpecificBundleName(const std::string &bundleName, int32_t appIndex, ++ std::string &specificBundleName) ++{ ++ return true; ++} ++ ++bool PreProcessUtils::GetSpecificBundleNameByTokenId(uint32_t tokenId, std::string &bundleName) ++{ ++ bundleName = "bundleName"; ++ return true; ++} ++} // namespace UDMF ++} // namespace OHOS +\ No newline at end of file +diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h +new file mode 100644 +index 0000000000000000000000000000000000000000..c13e8590bbd7275a769c0de184eb22f270853a77 +--- /dev/null ++++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h +@@ -0,0 +1,52 @@ ++/* ++ * 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. ++ */ ++#ifndef UDMF_PREPROCESS_UTILS_H ++#define UDMF_PREPROCESS_UTILS_H ++ ++#include "bundlemgr/bundle_mgr_proxy.h" ++#include "unified_data.h" ++ ++namespace OHOS { ++namespace UDMF { ++class PreProcessUtils { ++public: ++ static int32_t FillRuntimeInfo(UnifiedData &data, CustomOption &option); ++ static std::string GenerateId(); ++ static time_t GetTimestamp(); ++ static int32_t GetHapUidByToken(uint32_t tokenId, int &userId); ++ static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); ++ static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); ++ static std::string GetLocalDeviceId(); ++ static void SetRemoteData(UnifiedData &data); ++ static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); ++ static bool GetInstIndex(uint32_t tokenId, int32_t &instIndex); ++ static bool IsNetworkingEnabled(); ++ static void ProcessFileType(std::vector> records, ++ std::function)> callback); ++ static void GetHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); ++ static void ClearHtmlDfsUris(UnifiedData &data); ++ static void ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); ++ static void ProcessRecord(std::shared_ptr record, uint32_t tokenId, ++ bool isLocal, std::vector &uris); ++ static void SetRecordUid(UnifiedData &data); ++ static bool GetDetailsFromUData(const UnifiedData &data, UDDetails &details); ++ static Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); ++ static bool GetSpecificBundleNameByTokenId(uint32_t tokenId, std::string &bundleName); ++ static std::string GetAppId(const std::string &bundleName); ++ static sptr GetBundleMgr(); ++}; ++} // namespace UDMF ++} // namespace OHOS ++#endif // UDMF_PREPROCESS_UTILS_H +\ No newline at end of file +diff --git a/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp b/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp +new file mode 100644 +index 0000000000000000000000000000000000000000..7d5c7cc94d17191fada5e7ca9550cdbe6bc43b9f +--- /dev/null ++++ b/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp +@@ -0,0 +1,388 @@ ++/* ++* 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. ++*/ ++ ++#include "udmf_service_impl.h" ++ ++#include "accesstoken_kit.h" ++#include "bootstrap.h" ++#include "device_manager_adapter.h" ++#include "executor_pool.h" ++#include "gtest/gtest.h" ++#include "ipc_skeleton.h" ++#include "kvstore_meta_manager.h" ++#include "metadata/meta_data_manager.h" ++#include "nativetoken_kit.h" ++#include "preprocess_utils.h" ++#include "runtime_store.h" ++#include "text.h" ++#include "token_setproc.h" ++#include "runtime_store.h" ++#include "gtest/gtest.h" ++#include "kv_store_nb_delegate_corruption_mock.h" ++#include "account/account_delegate.h" ++ ++using namespace OHOS::UDMF; ++using namespace testing::ext; ++using namespace testing; ++using namespace OHOS::Security::AccessToken; ++using namespace OHOS::UDMF; ++using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; ++namespace OHOS::Test { ++namespace DistributedDataTest { ++constexpr const char *DATA_HUB_INTENTION = "DataHub"; ++class UdmfServiceImplDbCorruptionMockTest : public testing::Test { ++public: ++ static void SetUpTestCase(void); ++ static void TearDownTestCase(void) {}; ++ void SetUp() {}; ++ void TearDown() {}; ++}; ++ ++static void GrantPermissionNative() ++{ ++ const char **perms = new const char *[3]; ++ perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; ++ perms[1] = "ohos.permission.ACCESS_SERVICE_DM"; ++ perms[2] = "ohos.permission.MONITOR_DEVICE_NETWORK_STATE"; // perms[2] is a permission parameter ++ TokenInfoParams infoInstance = { ++ .dcapsNum = 0, ++ .permsNum = 3, ++ .aclsNum = 0, ++ .dcaps = nullptr, ++ .perms = perms, ++ .acls = nullptr, ++ .processName = "distributed_data_test", ++ .aplStr = "system_basic", ++ }; ++ uint64_t tokenId = GetAccessTokenId(&infoInstance); ++ SetSelfTokenID(tokenId); ++ AccessTokenKit::ReloadNativeTokenInfo(); ++ delete[] perms; ++} ++ ++void UdmfServiceImplDbCorruptionMockTest::SetUpTestCase(void) ++{ ++ GrantPermissionNative(); ++ DistributedData::Bootstrap::GetInstance().LoadComponents(); ++ DistributedData::Bootstrap::GetInstance().LoadDirectory(); ++ DistributedData::Bootstrap::GetInstance().LoadCheckers(); ++ size_t max = 2; ++ size_t min = 1; ++ auto executors = std::make_shared(max, min); ++ DmAdapter::GetInstance().Init(executors); ++ DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); ++ DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter(); ++ DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener(); ++} ++ ++/** ++* @tc.name: SaveDataTest001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, SaveDataTest001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string key = DATA_HUB_INTENTION; ++ auto store = std::make_shared(key); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ key.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(key, store); ++ CustomOption option { ++ .intention = Intention::UD_INTENTION_DATA_HUB, ++ .tokenId = 1 ++ }; ++ auto record = std::make_shared(); ++ UnifiedData data; ++ data.AddRecord(record); ++ std::string key1 = "key"; ++ UdmfServiceImpl serviceImpl; ++ auto status = serviceImpl.SaveData(option, data, key1); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++} ++ ++/** ++* @tc.name: RetrieveData001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, RetrieveData001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string intention = "drag"; ++ auto store = std::make_shared(intention); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ intention.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); ++ std::string key = "udmf://drag/get.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; ++ QueryOption option = { ++ .key = key ++ }; ++ UnifiedData data; ++ UdmfServiceImpl serviceImpl; ++ auto status = serviceImpl.RetrieveData(option, data); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++} ++ ++/** ++* @tc.name: DeleteData001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, DeleteData001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string intention = DATA_HUB_INTENTION; ++ auto store = std::make_shared(intention); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ intention.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); ++ std::string key = "udmf://DataHub/delete.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; ++ QueryOption option = { ++ .key = key, ++ }; ++ auto record = std::make_shared(); ++ UnifiedData data; ++ data.AddRecord(record); ++ std::vector dataList = { data }; ++ UdmfServiceImpl serviceImpl; ++ auto status = serviceImpl.DeleteData(option, dataList); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++} ++ ++/** ++* @tc.name: GetSummary001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetSummary001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string intention = DATA_HUB_INTENTION; ++ auto store = std::make_shared(intention); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ intention.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); ++ std::string key = "udmf://DataHub/summary.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; ++ QueryOption option = { ++ .key = key, ++ }; ++ Summary summary; ++ UdmfServiceImpl serviceImpl; ++ auto status = serviceImpl.GetSummary(option, summary); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++} ++ ++/** ++* @tc.name: IsRemoteData001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, IsRemoteData001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string intention = DATA_HUB_INTENTION; ++ auto store = std::make_shared(intention); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ intention.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); ++ std::string key = "udmf://DataHub/remote.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; ++ QueryOption option = { ++ .key = key, ++ }; ++ UdmfServiceImpl serviceImpl; ++ bool ret = false; ++ auto status = serviceImpl.IsRemoteData(option, ret); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++ EXPECT_FALSE(ret); ++} ++ ++/** ++* @tc.name: GetAppShareOption001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetAppShareOption001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string intention = DATA_HUB_INTENTION; ++ auto store = std::make_shared(intention); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ intention.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); ++ UdmfServiceImpl serviceImpl; ++ int32_t shareOption = CROSS_APP; ++ auto status = serviceImpl.GetAppShareOption("DataHub", shareOption); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++} ++ ++/** ++* @tc.name: QueryDataCommon001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, QueryDataCommon001, TestSize.Level1) ++{ ++ StoreCache::GetInstance().stores_.Clear(); ++ std::string intention = DATA_HUB_INTENTION; ++ auto store = std::make_shared(intention); ++ store->kvStore_ = std::make_shared(); ++ int foregroundUserId = 0; ++ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); ++ intention.append(std::to_string(foregroundUserId)); ++ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); ++ UdmfServiceImpl serviceImpl; ++ QueryOption option = { ++ .intention = Intention::UD_INTENTION_DATA_HUB, ++ }; ++ std::vector dataList; ++ std::shared_ptr store1; ++ auto status = serviceImpl.QueryDataCommon(option, dataList, store1); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); ++} ++ ++/** ++* @tc.name: PutLocal001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, PutLocal001, TestSize.Level1) ++{ ++ std::string key = "key"; ++ std::string value = "value"; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->PutLocal(key, value); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++ ++/** ++* @tc.name: GetLocal001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetLocal001, TestSize.Level1) ++{ ++ std::string key = "key"; ++ std::string value; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->GetLocal(key, value); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++ ++/** ++* @tc.name: DeleteLocal001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, DeleteLocal001, TestSize.Level1) ++{ ++ std::string key = "key"; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->DeleteLocal(key); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++ ++/** ++* @tc.name: PutRuntime001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, PutRuntime001, TestSize.Level1) ++{ ++ std::string key = "key"; ++ Runtime runtime; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->PutRuntime(key, runtime); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++ ++/** ++* @tc.name: GetRuntime001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetRuntime001, TestSize.Level1) ++{ ++ std::string key = "key"; ++ Runtime runtime; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->GetRuntime(key, runtime); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++ ++/** ++* @tc.name: Update001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, Update001, TestSize.Level1) ++{ ++ UnifiedData data; ++ auto rumtime = std::make_shared(); ++ UnifiedKey key(DATA_HUB_INTENTION, "com.demo.test", "111"); ++ rumtime->key = key; ++ data.runtime_ = rumtime; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->Update(data); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++ ++/** ++* @tc.name: Delete001 ++* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfServiceImplDbCorruptionMockTest, Delete001, TestSize.Level1) ++{ ++ std::string key = "key"; ++ auto store = std::make_shared(DATA_HUB_INTENTION); ++ store->kvStore_ = std::make_shared(); ++ auto status = store->Delete(key); ++ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); ++} ++}; // namespace DistributedDataTest ++}; // namespace OHOS::Test +\ No newline at end of file +diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +index 01795f4b167166759a80628c7b63c2ca4c14f8ee..f2d1b475e7fa4b3a3fe69916c10622e1b6d00683 100644 +--- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp ++++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +@@ -737,5 +737,33 @@ HWTEST_F(UdmfRunTimeStoreTest, OnAccountChanged001, TestSize.Level1) + SetSelfTokenID(0); + observer.OnAccountChanged(eventInfo, 0); + } ++ ++/** ++* @tc.name: MarkWhenCorrupted001 ++* @tc.desc: Normal testcase of MarkWhenCorrupted ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted001, TestSize.Level1) ++{ ++ DistributedDB::DBStatus status = DistributedDB::DBStatus::OK; ++ auto store = std::make_shared(STORE_ID); ++ store->MarkWhenCorrupted(status); ++ EXPECT_FALSE(store->isCorrupted); ++} ++ ++/** ++* @tc.name: MarkWhenCorrupted001 ++* @tc.desc: Normal testcase of MarkWhenCorrupted ++* @tc.type: FUNC ++* @tc.require: ++*/ ++HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted002, TestSize.Level1) ++{ ++ DistributedDB::DBStatus status = DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; ++ auto store = std::make_shared(STORE_ID); ++ store->MarkWhenCorrupted(status); ++ EXPECT_TRUE(store->isCorrupted); ++} + }; // namespace DistributedDataTest + }; // namespace OHOS::Test +\ No newline at end of file +diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +index 0bad354cbcba132bca066ed023a9220ac3b4061c..df04270310d8537259632563a6a0820919dad009 100644 +--- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp ++++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +@@ -588,5 +588,39 @@ HWTEST_F(UdmfServiceImplTest, ValidateAndProcessRuntimeData004, TestSize.Level1) + int32_t result = impl.ValidateAndProcessRuntimeData(dataSet, runtime, unifiedDataSet, query, deleteKeys); + EXPECT_EQ(result, UDMF::E_OK); + } ++ ++/** ++ * @tc.name: CloseStoreWhenCorrupted001 ++ * @tc.desc: Normal test of CloseStoreWhenCorrupted ++ * @tc.type: FUNC ++ */ ++HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted001, TestSize.Level1) ++{ ++ std::string intention = "drag"; ++ StoreCache::GetInstance().CloseStores(); ++ auto store = StoreCache::GetInstance().GetStore(intention); ++ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); ++ Status status = UDMF::E_OK; ++ UdmfServiceImpl impl; ++ impl.CloseStoreWhenCorrupted(intention, status); ++ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); ++} ++ ++/** ++ * @tc.name: CloseStoreWhenCorrupted002 ++ * @tc.desc: Abnormal test of CloseStoreWhenCorrupted ++ * @tc.type: FUNC ++ */ ++HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted002, TestSize.Level1) ++{ ++ std::string intention = "drag"; ++ StoreCache::GetInstance().CloseStores(); ++ auto store = StoreCache::GetInstance().GetStore(intention); ++ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); ++ Status status = UDMF::E_DB_CORRUPTED; ++ UdmfServiceImpl impl; ++ impl.CloseStoreWhenCorrupted(intention, status); ++ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 0); ++} + }; // namespace DistributedDataTest + }; // namespace OHOS::Test +diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp +index e218e7b1fdbf61a4159a727a935b6885adf36dd0..6b54d02a92be776b57d5dd2ba0d25b2906325461 100644 +--- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp ++++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp +@@ -60,7 +60,7 @@ Status RuntimeStore::PutLocal(const std::string &key, const std::string &value) + auto status = kvStore_->PutLocal(keyBytes, valueBytes); + if (status != DBStatus::OK) { + ZLOGE("KvStore PutLocal failed, status: %{public}d.", status); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(status); + } + return E_OK; + } +@@ -73,7 +73,7 @@ Status RuntimeStore::GetLocal(const std::string &key, std::string &value) + DBStatus status = kvStore_->GetLocal(keyBytes, valueBytes); + if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { + ZLOGE("GetLocal entry failed, key: %{public}s.", key.c_str()); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(status); + } + if (valueBytes.empty()) { + ZLOGW("GetLocal entry is empty, key: %{public}s", key.c_str()); +@@ -91,7 +91,7 @@ Status RuntimeStore::DeleteLocal(const std::string &key) + DBStatus status = kvStore_->DeleteLocal(keyBytes); + if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { + ZLOGE("DeleteLocal failed, key: %{public}s.", key.c_str()); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(status); + } + return E_OK; + } +@@ -115,9 +115,10 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) + { + UpdateTime(); + std::vector entries; +- if (GetEntries(UnifiedKey(key).GetKeyCommonPrefix(), entries) != E_OK) { ++ auto status = GetEntries(UnifiedKey(key).GetKeyCommonPrefix(), entries); ++ if (status != E_OK) { + ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); +- return E_DB_ERROR; ++ return status; + } + if (entries.empty()) { + ZLOGW("entries is empty, dataPrefix: %{public}s", key.c_str()); +@@ -173,9 +174,10 @@ Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) + ZLOGW("Get stored summary failed, key: %{public}s, status:%{public}d", summaryKey.c_str(), res); + UnifiedData unifiedData; + auto udKey = key.GetUnifiedKey(); +- if (Get(udKey, unifiedData) != E_OK) { ++ auto status = Get(udKey, unifiedData); ++ if (status != E_OK) { + ZLOGE("Get unified data failed, key: %{public}s", udKey.c_str()); +- return E_DB_ERROR; ++ return status; + } + UDDetails details {}; + if (PreProcessUtils::GetDetailsFromUData(unifiedData, details)) { +@@ -204,7 +206,7 @@ Status RuntimeStore::PutRuntime(const std::string &key, const Runtime &runtime) + auto res = kvStore_->Put({key.begin(), key.end()}, value); + if (res != OK) { + ZLOGE("Put failed, key:%{public}s, status:%{public}d", key.c_str(), res); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(res); + } + return E_OK; + } +@@ -220,7 +222,7 @@ Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) + } + if (res != OK || value.empty()) { + ZLOGE("Get failed, key: %{public}s, status:%{public}d", key.c_str(), res); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(res); + } + auto status = DataHandler::UnmarshalEntries(value, runtime, TAG::TAG_RUNTIME); + if (status != E_OK) { +@@ -233,14 +235,16 @@ Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) + Status RuntimeStore::Update(const UnifiedData &unifiedData) + { + std::string key = unifiedData.GetRuntime()->key.key; +- if (Delete(UnifiedKey(key).GetKeyCommonPrefix()) != E_OK) { ++ auto status = Delete(UnifiedKey(key).GetKeyCommonPrefix()); ++ if (status != E_OK) { + UpdateTime(); + ZLOGE("Delete unified data failed, dataPrefix: %{public}s.", key.c_str()); +- return E_DB_ERROR; ++ return status; + } +- if (Put(unifiedData) != E_OK) { ++ status = Put(unifiedData); ++ if (status != E_OK) { + ZLOGE("Update unified data failed, dataPrefix: %{public}s.", key.c_str()); +- return E_DB_ERROR; ++ return status; + } + return E_OK; + } +@@ -248,9 +252,10 @@ Status RuntimeStore::Update(const UnifiedData &unifiedData) + Status RuntimeStore::Delete(const std::string &key) + { + std::vector entries; +- if (GetEntries(key, entries) != E_OK) { ++ auto status = GetEntries(key, entries); ++ if (status != E_OK) { + ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); +- return E_DB_ERROR; ++ return status; + } + if (entries.empty()) { + ZLOGD("entries is empty."); +@@ -382,7 +387,7 @@ Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector(status)); ++ if (delegateManager_->DeleteKvStore(storeId_) != DBStatus::OK) { ++ ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(status)); ++ } ++ return false; ++ } + if (status != DBStatus::OK) { + ZLOGE("GetKvStore fail, status: %{public}d.", static_cast(status)); + return false; +@@ -442,6 +454,13 @@ bool RuntimeStore::Init() + if (retStatus != DBStatus::OK) { + ZLOGE("CloseKvStore fail, status: %{public}d.", static_cast(retStatus)); + } ++ if (isCorrupted) { ++ ZLOGI("start to delete runtime kvStore."); ++ retStatus = delegateManager_->DeleteKvStore(storeId_); ++ if (retStatus != DBStatus::OK) { ++ ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(retStatus)); ++ } ++ } + }; + kvStore_ = std::shared_ptr(delegate, release); + uint32_t pragmData = 16 * 1024 * 1024; +@@ -549,7 +568,7 @@ Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vectorGetEntries(dbQuery, entries); + if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { + ZLOGE("KvStore getEntries failed, status: %{public}d.", static_cast(status)); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(status); + } + return E_OK; + } +@@ -559,7 +578,7 @@ Status RuntimeStore::PutEntries(const std::vector &entries) + DBStatus status = kvStore_->PutBatch(entries); + if (status != DBStatus::OK) { + ZLOGE("putBatch failed, status: %{public}d.", status); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(status); + } + return E_OK; + } +@@ -569,10 +588,19 @@ Status RuntimeStore::DeleteEntries(const std::vector &keys) + DBStatus status = kvStore_->DeleteBatch(keys); + if (status != DBStatus::OK) { + ZLOGE("deleteBatch failed, status: %{public}d.", status); +- return E_DB_ERROR; ++ return MarkWhenCorrupted(status); + } + return E_OK; + } + ++Status RuntimeStore::MarkWhenCorrupted(DistributedDB::DBStatus status) ++{ ++ if (status == INVALID_PASSWD_OR_CORRUPTED_DB) { ++ ZLOGE("Kv database corrupted"); ++ isCorrupted = true; ++ return E_DB_CORRUPTED; ++ } ++ return E_DB_ERROR; ++} + } // namespace UDMF + } // namespace OHOS +\ No newline at end of file +diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h +index d5f4be1a84c048369bd9e3bb5f52fde1cf951f23..421151f80e113ba2819d31aa60c28c8405096b3f 100644 +--- a/services/distributeddataservice/service/udmf/store/runtime_store.h ++++ b/services/distributeddataservice/service/udmf/store/runtime_store.h +@@ -64,6 +64,9 @@ private: + void NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, + const DevNameMap &deviceNameMap); + Status PutSummary(const UnifiedData &data, std::vector &entries); ++ Status MarkWhenCorrupted(DistributedDB::DBStatus status); ++ bool isCorrupted = false; ++ + }; + } // namespace UDMF + } // namespace OHOS +diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp +index 545b549a17b0145ca1a1957ba92ce5c7986594c9..30ae5c7a160c9c86cb5b23ea7f703e557b6f1f88 100644 +--- a/services/distributeddataservice/service/udmf/store/store_cache.cpp ++++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp +@@ -38,7 +38,6 @@ std::shared_ptr StoreCache::GetStore(std::string intention) + } + std::string key = intention; + key.append(std::to_string(foregroundUserId)); +- + stores_.Compute(key, [&store, intention](const auto &key, std::shared_ptr &storePtr) -> bool { + if (storePtr != nullptr) { + store = storePtr; +@@ -56,7 +55,6 @@ std::shared_ptr StoreCache::GetStore(std::string intention) + } + return false; + }); +- + std::unique_lock lock(taskMutex_); + if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) { + taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); +@@ -94,6 +92,19 @@ void StoreCache::CloseStores() + stores_.Clear(); + } + ++void StoreCache::RemoveStore(std::string intention) ++{ ++ ZLOGI("RemoveStore, intention:%{public}s", intention.c_str()); ++ int foregroundUserId = 0; ++ if (!DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId)) { ++ ZLOGE("QueryForegroundUserId failed."); ++ return; ++ } ++ std::string key = intention; ++ key.append(std::to_string(foregroundUserId)); ++ stores_.Erase(key); ++} ++ + bool StoreCache::IsValidIntention(const std::string &intention) + { + return UnifiedDataUtils::GetIntentionByString(intention) != UD_INTENTION_BUTT; +diff --git a/services/distributeddataservice/service/udmf/store/store_cache.h b/services/distributeddataservice/service/udmf/store/store_cache.h +index 5d3918d2d0bd44121b6e8f7618eade4103ff3358..b71481dbea8990f8b63682bbd48eb6a3eec79d38 100644 +--- a/services/distributeddataservice/service/udmf/store/store_cache.h ++++ b/services/distributeddataservice/service/udmf/store/store_cache.h +@@ -28,6 +28,7 @@ public: + static StoreCache &GetInstance(); + void SetThreadPool(std::shared_ptr executors); + void CloseStores(); ++ void RemoveStore(std::string intention); + + private: + StoreCache() {} +diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +index bade1ef4fd9bb6b01e5f1990ee3682eae09181a3..9c8bc2e4a11a6265790fa8a34417aedb89d89eef 100644 +--- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp ++++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +@@ -128,18 +128,15 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData + ZLOGE("UnifiedData is invalid."); + return E_INVALID_PARAMETERS; + } +- + if (!UnifiedDataUtils::IsValidIntention(option.intention)) { + ZLOGE("Invalid parameters intention: %{public}d.", option.intention); + return E_INVALID_PARAMETERS; + } +- + // imput runtime info before put it into store and save one privilege + if (PreProcessUtils::FillRuntimeInfo(unifiedData, option) != E_OK) { + ZLOGE("Imputation failed"); + return E_ERROR; + } +- + std::string intention = unifiedData.GetRuntime()->key.intention; + if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { + int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); +@@ -155,9 +152,10 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData + ZLOGE("Get store failed:%{public}s", intention.c_str()); + return E_DB_ERROR; + } +- +- if (store->Put(unifiedData) != E_OK) { +- ZLOGE("Put unified data failed:%{public}s", intention.c_str()); ++ auto status = store->Put(unifiedData); ++ if (status != E_OK) { ++ ZLOGE("Put unified data failed:%{public}s, status:%{public}d", intention.c_str(), status); ++ CloseStoreWhenCorrupted(intention, status); + return E_DB_ERROR; + } + key = unifiedData.GetRuntime()->key.GetUnifiedKey(); +@@ -223,7 +221,8 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni + int32_t res = store->Get(query.key, unifiedData); + if (res != E_OK) { + ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str()); +- return res; ++ CloseStoreWhenCorrupted(key.intention, static_cast(res)); ++ return E_DB_ERROR; + } + + if (!unifiedData.IsComplete()) { +@@ -420,6 +419,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi + int32_t res = store->Get(query.key, data); + if (res != E_OK) { + ZLOGE("Get data failed:%{public}s", key.intention.c_str()); ++ CloseStoreWhenCorrupted(key.intention, static_cast(res)); + return res; + } + if (data.IsEmpty()) { +@@ -440,8 +440,10 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi + runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); + unifiedData.SetRuntime(*runtime); + PreProcessUtils::SetRecordUid(unifiedData); +- if (store->Update(unifiedData) != E_OK) { ++ res = store->Update(unifiedData); ++ if (res != E_OK) { + ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); ++ CloseStoreWhenCorrupted(key.intention, static_cast(res)); + return E_DB_ERROR; + } + return E_OK; +@@ -480,7 +482,8 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector(status)); ++ return E_DB_ERROR; + } + if (dataSet.empty()) { + ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); +@@ -498,8 +501,10 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorDeleteBatch(deleteKeys) != E_OK) { ++ status = store->DeleteBatch(deleteKeys); ++ if (status != E_OK) { + ZLOGE("Remove data failed."); ++ CloseStoreWhenCorrupted(key.intention, static_cast(status)); + return E_DB_ERROR; + } + return E_OK; +@@ -551,9 +556,10 @@ int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) + ZLOGE("Get store failed:%{public}s", key.intention.c_str()); + return E_DB_ERROR; + } +- +- if (store->GetSummary(key, summary) != E_OK) { ++ auto status = store->GetSummary(key, summary); ++ if (status != E_OK) { + ZLOGE("Store get summary failed:%{public}s", key.intention.c_str()); ++ CloseStoreWhenCorrupted(key.intention, status); + return E_DB_ERROR; + } + return E_OK; +@@ -598,14 +604,17 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi + } + if (res != E_OK) { + ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); ++ CloseStoreWhenCorrupted(key.intention, res); + return res; + } + runtime.privileges.emplace_back(privilege); + res = store->PutRuntime(query.key, runtime); + if (res != E_OK) { + ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); ++ CloseStoreWhenCorrupted(key.intention, res); ++ return E_DB_ERROR; + } +- return res; ++ return E_OK; + } + + int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) +@@ -715,6 +724,7 @@ int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result) + auto res = store->GetRuntime(query.key, runtime); + if (res != E_OK) { + ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); ++ CloseStoreWhenCorrupted(key.intention, res); + return E_DB_ERROR; + } + +@@ -751,9 +761,10 @@ int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t + ZLOGE("SetAppShareOption failed,shareOption already set:%{public}s", shareOptionTmp.c_str()); + return E_SETTINGS_EXISTED; + } +- +- if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) { +- ZLOGE("Store get unifiedData failed:%{public}d", shareOption); ++ auto status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)); ++ if (status != E_OK) { ++ ZLOGE("Store get unifiedData failed:%{public}d", status); ++ CloseStoreWhenCorrupted(intention, status); + return E_DB_ERROR; + } + return E_OK; +@@ -775,7 +786,8 @@ int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t + int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); + if (ret != E_OK) { + ZLOGW("GetLocal failed:%{public}s", intention.c_str()); +- return ret; ++ CloseStoreWhenCorrupted(intention, static_cast(ret)); ++ return E_DB_ERROR; + } + ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str()); + shareOption = ShareOptionsUtil::GetEnumNum(appShareOption); +@@ -802,8 +814,10 @@ int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) + } + + UnifiedData unifiedData; +- if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) { +- ZLOGE("Store DeleteLocal failed:%{public}s", intention.c_str()); ++ auto status = store->DeleteLocal(std::to_string(accessTokenIDEx)); ++ if (status != E_OK) { ++ ZLOGE("Store DeleteLocal failed:%{public}s, status:%{public}d", intention.c_str(), status); ++ CloseStoreWhenCorrupted(intention, status); + return E_DB_ERROR; + } + return E_OK; +@@ -849,8 +863,10 @@ int32_t UdmfServiceImpl::QueryDataCommon( + ZLOGE("Get store failed:%{public}s", intention.c_str()); + return E_DB_ERROR; + } +- if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { +- ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); ++ auto status = store->GetBatchData(dataPrefix, dataSet); ++ if (status != E_OK) { ++ ZLOGE("Get dataSet failed, dataPrefix: %{public}s, status:%{public}d.", dataPrefix.c_str(), status); ++ CloseStoreWhenCorrupted(intention, status); + return E_DB_ERROR; + } + return E_OK; +@@ -1135,8 +1151,10 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptrPutSummary(udkey, summary) != E_OK) { +- ZLOGE("Put summary failed:%{public}s", key.c_str()); ++ auto status = store->PutSummary(udkey, summary); ++ if (status != E_OK) { ++ ZLOGE("Put summary failed:%{public}s, status:%{public}d", key.c_str(), status); ++ CloseStoreWhenCorrupted(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status); + return E_DB_ERROR; + } + return E_OK; +@@ -1239,5 +1257,13 @@ bool UdmfServiceImpl::IsValidInput(const QueryOption &query, UnifiedData &unifie + } + return true; + } ++ ++void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, Status status) ++{ ++ if (status == E_DB_CORRUPTED) { ++ ZLOGE("Kv database corrupted, start to remove store"); ++ StoreCache::GetInstance().RemoveStore(intention); ++ } ++} + } // namespace UDMF + } // namespace OHOS +\ No newline at end of file +diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h +index b728d8199086fc592b8692696904d4f00be01c4c..f8aed0684b73fa97ebd57c9f531536792d569771 100644 +--- a/services/distributeddataservice/service/udmf/udmf_service_impl.h ++++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h +@@ -83,6 +83,7 @@ private: + int32_t ValidateAndProcessRuntimeData(const std::vector &dataSet, std::shared_ptr runtime, + std::vector &unifiedDataSet, const QueryOption &query, std::vector &deleteKeys); + int32_t CheckAppId(std::shared_ptr runtime, const std::string &bundleName); ++ void CloseStoreWhenCorrupted(const std::string &intention, Status status); + class Factory { + public: + Factory(); diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index c46be0222..a4956c069 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -2105,6 +2105,94 @@ ohos_unittest("BackupManagerServiceTest") { ] } +ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { + module_out_path = module_output_path + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "${datamgr_service_path}/cfi_blocklist.txt" + } + sources = [ + "udmf_db_corruption_mock_test.cpp", + "mock/kv_store_nb_delegate_corruption_mock.cpp", + "mock/preprocess_utils_mock.cpp", + "${data_service_path}/service/udmf/udmf_service_impl.cpp", + "${data_service_path}/service/udmf/lifecycle/clean_on_startup.cpp", + "${data_service_path}/service/udmf/lifecycle/clean_on_timeout.cpp", + "${data_service_path}/service/udmf/lifecycle/lifecycle_manager.cpp", + "${data_service_path}/service/udmf/lifecycle/lifecycle_policy.cpp", + "${data_service_path}/service/udmf/permission/checker_manager.cpp", + "${data_service_path}/service/udmf/permission/data_checker.cpp", + "${data_service_path}/service/udmf/permission/uri_permission_manager.cpp", + "${data_service_path}/service/udmf/preprocess/data_handler.cpp", + "${data_service_path}/service/udmf/preprocess/udmf_notifier_proxy.cpp", + "${data_service_path}/service/udmf/store/runtime_store.cpp", + "${data_service_path}/service/udmf/store/store_account_observer.cpp", + "${data_service_path}/service/udmf/store/store_cache.cpp", + "${data_service_path}/service/udmf/udmf_service_stub.cpp", + "${data_service_path}/app/src/kvstore_meta_manager.cpp", + ] + + include_dirs = [ + "${data_service_path}/adapter/include/account", + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/app/src", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/udmf", + "${data_service_path}/service/udmf/store", + "${data_service_path}/service/udmf/preprocess", + "${data_service_path}/service/udmf/permission", + "${data_service_path}/service/test/mock", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "ability_base:base", + "ability_base:zuri", + "ability_base:want", + "ability_runtime:uri_permission_mgr", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken_shared", + "access_token:libtoken_setproc", + "access_token:libtokenid_sdk", + "app_file_service:remote_file_share_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "device_manager:devicemanagersdk", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "kv_store:distributeddata_mgr", + "udmf:udmf_client", + "udmf:utd_client", + "dsoftbus:softbus_client", + "samgr:samgr_proxy", + "safwk:system_ability_fwk", + "openssl:libcrypto_shared", + "googletest:gmock_main", + "googletest:gtest_main", + "dataclassification:data_transit_mgr", + ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + ] + + defines = [ + "private=public", + "protected=public", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -2133,6 +2221,7 @@ group("unittest") { ":UdmfRunTimeStoreTest", ":UdmfServiceImplMockTest", ":UdmfServiceImplTest", + ":UdmfServiceImplDbCorruptionMockTest", ":UdmfServiceStubMockTest", ":UdmfServiceStubTest", ] diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp new file mode 100644 index 000000000..04a12f2a0 --- /dev/null +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2024 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 "kv_store_nb_delegate_corruption_mock.h" + +#include "store_types.h" +namespace DistributedDB { +DBStatus KvStoreNbDelegateCorruptionMock::Get(const Key &key, Value &value) const +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, std::vector &entries) const +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, KvStoreResultSet *&resultSet) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetCount(const Query &query, int &count) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::CloseResultSet(KvStoreResultSet *&resultSet) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Put(const Key &key, const Value &value) +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::PutBatch(const std::vector &entries) +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::DeleteBatch(const std::vector &keys) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Delete(const Key &key) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetLocal(const Key &key, Value &value) const +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetLocalEntries(const Key &keyPrefix, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::PutLocal(const Key &key, const Value &value) +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocal(const Key &key) +{ + return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; +} + +DBStatus KvStoreNbDelegateCorruptionMock::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, + const KvStoreNbPublishOnConflict &onConflict) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RegisterObserver(const Key &key, unsigned int mode, + KvStoreObserver *observer) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UnRegisterObserver(const KvStoreObserver *observer) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device) +{ + return DBStatus::OK; +} + +std::string KvStoreNbDelegateCorruptionMock::GetStoreId() const +{ + return "ok"; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Pragma(PragmaCmd cmd, PragmaData ¶mData) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetConflictNotifier(int conflictType, + const KvStoreNbConflictNotifier ¬ifier) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Rekey(const CipherPassword &password) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Export(const std::string &filePath, + const CipherPassword &passwd, bool force) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Import(const std::string &filePath, const CipherPassword &passwd, + bool isNeedIntegrityCheck) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::StartTransaction() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Commit() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Rollback() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::PutLocalBatch(const std::vector &entries) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocalBatch(const std::vector &keys) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetSecurityOption(SecurityOption &option) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::CheckIntegrity() const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetEqualIdentifier(const std::string &identifier, + const std::vector &targets) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetPushDataInterceptor(const PushDataInterceptor &interceptor) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UnSubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetKeys(const Key &keyPrefix, std::vector &keys) const +{ + return DBStatus::OK; +} + +size_t KvStoreNbDelegateCorruptionMock::GetSyncDataSize(const std::string &device) const +{ + size_t size = 0; + return size; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UpdateKey(const UpdateKeyCallback &callback) +{ + return DBStatus::OK; +} + +std::pair KvStoreNbDelegateCorruptionMock::GetWatermarkInfo(const std::string &device) +{ + std::pair ret; + return ret; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDB(const std::map> &cloudDBs) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDbSchema(const std::map &schema) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, ClearMode mode) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) +{ + return DBStatus::OK; +} + +int32_t KvStoreNbDelegateCorruptionMock::GetTaskCount() +{ + int32_t taskCount = taskCountMock_; + return taskCount; +} + +void KvStoreNbDelegateCorruptionMock::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) +{ + auto callback_ = callback; +} + +std::pair> KvStoreNbDelegateCorruptionMock::GetCloudVersion( + const std::string &device) +{ + if (device.empty()) { + return { DBStatus::OK, {} }; + } else if (device == "test") { + return { DBStatus::DB_ERROR, {} }; + } else if (device == "device") { + return { DBStatus::DB_ERROR, {{device, device}} }; + } else { + return { DBStatus::OK, {{device, device}} }; + } +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetDeviceEntries(const std::string &device, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::CancelSync(uint32_t syncId) +{ + return DBStatus::OK; +} + +KvStoreNbDelegate::DatabaseStatus KvStoreNbDelegateCorruptionMock::GetDatabaseStatus() const +{ + return {}; +} + +DBStatus KvStoreNbDelegateCorruptionMock::ClearMetaData(ClearKvMetaDataOption option) +{ + return DBStatus::OK; +} +} // namespace DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h new file mode 100644 index 000000000..16176d2a3 --- /dev/null +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 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 KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK +#define KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK + +#include +#include +#include + +#include "cloud/cloud_store_types.h" +#include "cloud/icloud_db.h" +#include "intercepted_data.h" +#include "iprocess_system_api_adapter.h" +#include "kv_store_nb_conflict_data.h" +#include "kv_store_nb_delegate.h" +#include "kv_store_observer.h" +#include "kv_store_result_set.h" +#include "query.h" +#include "store_types.h" + +namespace DistributedDB { +class KvStoreNbDelegateCorruptionMock : public DistributedDB::KvStoreNbDelegate { +public: + int32_t taskCountMock_ = 0; + ~KvStoreNbDelegateCorruptionMock() = default; + DBStatus Get(const Key &key, Value &value) const; + DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const; + DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const; + DBStatus GetEntries(const Query &query, std::vector &entries) const; + DBStatus GetEntries(const Query &query, KvStoreResultSet *&resultSet) const; + DBStatus GetCount(const Query &query, int &count) const; + DBStatus CloseResultSet(KvStoreResultSet *&resultSet); + DBStatus Put(const Key &key, const Value &value); + DBStatus PutBatch(const std::vector &entries); + DBStatus DeleteBatch(const std::vector &keys); + DBStatus Delete(const Key &key); + DBStatus GetLocal(const Key &key, Value &value) const; + DBStatus GetLocalEntries(const Key &keyPrefix, std::vector &entries) const; + DBStatus PutLocal(const Key &key, const Value &value); + DBStatus DeleteLocal(const Key &key); + DBStatus PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, + const KvStoreNbPublishOnConflict &onConflict); + DBStatus UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp); + DBStatus RegisterObserver(const Key &key, unsigned int mode, KvStoreObserver *observer); + DBStatus UnRegisterObserver(const KvStoreObserver *observer); + DBStatus RemoveDeviceData(const std::string &device); + std::string GetStoreId() const; + DBStatus Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + bool wait = false); + DBStatus Pragma(PragmaCmd cmd, PragmaData ¶mData); + DBStatus SetConflictNotifier(int conflictType, + const KvStoreNbConflictNotifier ¬ifier); + DBStatus Rekey(const CipherPassword &password); + DBStatus Export(const std::string &filePath, const CipherPassword &passwd, bool force = false); + DBStatus Import(const std::string &filePath, const CipherPassword &passwd, bool isNeedIntegrityCheck = false); + DBStatus StartTransaction(); + DBStatus Commit(); + DBStatus Rollback(); + DBStatus PutLocalBatch(const std::vector &entries); + DBStatus DeleteLocalBatch(const std::vector &keys); + DBStatus GetSecurityOption(SecurityOption &option) const; + DBStatus SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier); + DBStatus Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait); + DBStatus CheckIntegrity() const; + DBStatus SetEqualIdentifier(const std::string &identifier, + const std::vector &targets); + DBStatus SetPushDataInterceptor(const PushDataInterceptor &interceptor); + DBStatus SubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait); + DBStatus UnSubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait); + DBStatus RemoveDeviceData(); + DBStatus GetKeys(const Key &keyPrefix, std::vector &keys) const; + size_t GetSyncDataSize(const std::string &device) const; + DBStatus UpdateKey(const UpdateKeyCallback &callback); + std::pair GetWatermarkInfo(const std::string &device); + DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess); + DBStatus SetCloudDB(const std::map> &cloudDBs); + DBStatus SetCloudDbSchema(const std::map &schema); + DBStatus RemoveDeviceData(const std::string &device, ClearMode mode); + DBStatus RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode); + int32_t GetTaskCount(); + void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback); + std::pair> GetCloudVersion( + const std::string &device); + DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor); + DBStatus SetCloudSyncConfig(const CloudSyncConfig &config); + DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const; + DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess); + DBStatus CancelSync(uint32_t syncId); + DatabaseStatus GetDatabaseStatus() const; + DBStatus ClearMetaData(ClearKvMetaDataOption option); +}; +} // namespace DistributedDB +#endif // KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp new file mode 100644 index 000000000..af03ce4d6 --- /dev/null +++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp @@ -0,0 +1,204 @@ +/* + * 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. + */ +#define LOG_TAG "PreProcessUtils" + +#include "preprocess_utils.h" + +#include "bundle_info.h" +#include "dds_trace.h" +#include "udmf_radar_reporter.h" +#include "accesstoken_kit.h" +#include "device_manager_adapter.h" +#include "file_mount_manager.h" +#include "iservice_registry.h" +#include "log_print.h" +#include "system_ability_definition.h" +#include "udmf_radar_reporter.h" +#include "udmf_utils.h" +#include "utils/crypto.h" +#include "uri_permission_manager_client.h" +#include "ipc_skeleton.h" +#include "bundle_mgr_interface.h" +namespace OHOS { +namespace UDMF { +using namespace OHOS::DistributedDataDfx; +using namespace Security::AccessToken; +using namespace OHOS::AppFileService::ModuleRemoteFileShare; +using namespace RadarReporter; + +int32_t PreProcessUtils::FillRuntimeInfo(UnifiedData &data, CustomOption &option) +{ + auto it = UD_INTENTION_MAP.find(option.intention); + if (it == UD_INTENTION_MAP.end()) { + return E_ERROR; + } + std::string bundleName = "bundleName"; + std::string intention = it->second; + UnifiedKey key(intention, bundleName, GenerateId()); + Privilege privilege; + privilege.tokenId = option.tokenId; + + Runtime runtime; + runtime.key = key; + runtime.privileges.emplace_back(privilege); + runtime.createTime = GetTimestamp(); + runtime.sourcePackage = bundleName; + runtime.createPackage = bundleName; + runtime.recordTotalNum = static_cast(data.GetRecords().size()); + runtime.tokenId = option.tokenId; + runtime.visibility = option.visibility; + runtime.appId = "appId"; + data.SetRuntime(runtime); + return E_OK; +} + +std::string PreProcessUtils::GenerateId() +{ + return "1122ac"; +} + +time_t PreProcessUtils::GetTimestamp() +{ + std::chrono::time_point tp = + std::chrono::time_point_cast(std::chrono::system_clock::now()); + time_t timestamp = tp.time_since_epoch().count(); + return timestamp; +} + +int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId, int &userId) +{ + userId = 100; + return E_OK; +} + +bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName) +{ + bundleName = "processName"; + return true; + +} + +bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName) +{ + processName = "processName"; + return true; +} + +std::string PreProcessUtils::GetAppId(const std::string &bundleName) +{ + return "com.demo.test"; +} + +std::string PreProcessUtils::GetLocalDeviceId() +{ + return "123"; +} + +void PreProcessUtils::SetRemoteData(UnifiedData &data) +{ + return; +} + +int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) +{ + return E_OK; +} + +bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex) +{ + return true; +} + +bool PreProcessUtils::IsNetworkingEnabled() +{ + return true; +} + +void PreProcessUtils::ProcessFileType(std::vector> records, + std::function)> callback) +{ + return; +} + +void PreProcessUtils::ProcessRecord(std::shared_ptr record, uint32_t tokenId, + bool isLocal, std::vector &uris) +{ + return; +} + +void PreProcessUtils::GetHtmlFileUris(uint32_t tokenId, UnifiedData &data, + bool isLocal, std::vector &uris) +{ + return; +} + +void PreProcessUtils::ClearHtmlDfsUris(UnifiedData &data) +{ + return; +} + +void PreProcessUtils::ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris) +{ + return; +} + +void PreProcessUtils::SetRecordUid(UnifiedData &data) +{ + return; +} + +bool PreProcessUtils::GetDetailsFromUData(const UnifiedData &data, UDDetails &details) +{ + return true; +} + +Status PreProcessUtils::GetSummaryFromDetails(const UDDetails &details, Summary &summary) +{ + return E_OK; +} + +sptr PreProcessUtils::GetBundleMgr() +{ + auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + ZLOGE("Failed to get system ability mgr."); + return nullptr; + } + auto bundleMgrProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (bundleMgrProxy == nullptr) { + ZLOGE("Failed to Get BMS SA."); + return nullptr; + } + auto bundleManager = iface_cast(bundleMgrProxy); + if (bundleManager == nullptr) { + ZLOGE("Failed to get bundle manager"); + return nullptr; + } + return bundleManager; +} + +bool PreProcessUtils::GetSpecificBundleName(const std::string &bundleName, int32_t appIndex, + std::string &specificBundleName) +{ + return true; +} + +bool PreProcessUtils::GetSpecificBundleNameByTokenId(uint32_t tokenId, std::string &bundleName) +{ + bundleName = "bundleName"; + return true; +} +} // namespace UDMF +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h new file mode 100644 index 000000000..c13e8590b --- /dev/null +++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h @@ -0,0 +1,52 @@ +/* + * 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. + */ +#ifndef UDMF_PREPROCESS_UTILS_H +#define UDMF_PREPROCESS_UTILS_H + +#include "bundlemgr/bundle_mgr_proxy.h" +#include "unified_data.h" + +namespace OHOS { +namespace UDMF { +class PreProcessUtils { +public: + static int32_t FillRuntimeInfo(UnifiedData &data, CustomOption &option); + static std::string GenerateId(); + static time_t GetTimestamp(); + static int32_t GetHapUidByToken(uint32_t tokenId, int &userId); + static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); + static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); + static std::string GetLocalDeviceId(); + static void SetRemoteData(UnifiedData &data); + static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); + static bool GetInstIndex(uint32_t tokenId, int32_t &instIndex); + static bool IsNetworkingEnabled(); + static void ProcessFileType(std::vector> records, + std::function)> callback); + static void GetHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); + static void ClearHtmlDfsUris(UnifiedData &data); + static void ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); + static void ProcessRecord(std::shared_ptr record, uint32_t tokenId, + bool isLocal, std::vector &uris); + static void SetRecordUid(UnifiedData &data); + static bool GetDetailsFromUData(const UnifiedData &data, UDDetails &details); + static Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); + static bool GetSpecificBundleNameByTokenId(uint32_t tokenId, std::string &bundleName); + static std::string GetAppId(const std::string &bundleName); + static sptr GetBundleMgr(); +}; +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_PREPROCESS_UTILS_H \ No newline at end of file diff --git a/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp b/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp new file mode 100644 index 000000000..7d5c7cc94 --- /dev/null +++ b/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp @@ -0,0 +1,388 @@ +/* +* 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. +*/ + +#include "udmf_service_impl.h" + +#include "accesstoken_kit.h" +#include "bootstrap.h" +#include "device_manager_adapter.h" +#include "executor_pool.h" +#include "gtest/gtest.h" +#include "ipc_skeleton.h" +#include "kvstore_meta_manager.h" +#include "metadata/meta_data_manager.h" +#include "nativetoken_kit.h" +#include "preprocess_utils.h" +#include "runtime_store.h" +#include "text.h" +#include "token_setproc.h" +#include "runtime_store.h" +#include "gtest/gtest.h" +#include "kv_store_nb_delegate_corruption_mock.h" +#include "account/account_delegate.h" + +using namespace OHOS::UDMF; +using namespace testing::ext; +using namespace testing; +using namespace OHOS::Security::AccessToken; +using namespace OHOS::UDMF; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +namespace OHOS::Test { +namespace DistributedDataTest { +constexpr const char *DATA_HUB_INTENTION = "DataHub"; +class UdmfServiceImplDbCorruptionMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void) {}; + void SetUp() {}; + void TearDown() {}; +}; + +static void GrantPermissionNative() +{ + const char **perms = new const char *[3]; + perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; + perms[1] = "ohos.permission.ACCESS_SERVICE_DM"; + perms[2] = "ohos.permission.MONITOR_DEVICE_NETWORK_STATE"; // perms[2] is a permission parameter + TokenInfoParams infoInstance = { + .dcapsNum = 0, + .permsNum = 3, + .aclsNum = 0, + .dcaps = nullptr, + .perms = perms, + .acls = nullptr, + .processName = "distributed_data_test", + .aplStr = "system_basic", + }; + uint64_t tokenId = GetAccessTokenId(&infoInstance); + SetSelfTokenID(tokenId); + AccessTokenKit::ReloadNativeTokenInfo(); + delete[] perms; +} + +void UdmfServiceImplDbCorruptionMockTest::SetUpTestCase(void) +{ + GrantPermissionNative(); + DistributedData::Bootstrap::GetInstance().LoadComponents(); + DistributedData::Bootstrap::GetInstance().LoadDirectory(); + DistributedData::Bootstrap::GetInstance().LoadCheckers(); + size_t max = 2; + size_t min = 1; + auto executors = std::make_shared(max, min); + DmAdapter::GetInstance().Init(executors); + DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); + DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter(); + DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener(); +} + +/** +* @tc.name: SaveDataTest001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, SaveDataTest001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string key = DATA_HUB_INTENTION; + auto store = std::make_shared(key); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + key.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(key, store); + CustomOption option { + .intention = Intention::UD_INTENTION_DATA_HUB, + .tokenId = 1 + }; + auto record = std::make_shared(); + UnifiedData data; + data.AddRecord(record); + std::string key1 = "key"; + UdmfServiceImpl serviceImpl; + auto status = serviceImpl.SaveData(option, data, key1); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); +} + +/** +* @tc.name: RetrieveData001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, RetrieveData001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string intention = "drag"; + auto store = std::make_shared(intention); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + intention.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); + std::string key = "udmf://drag/get.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; + QueryOption option = { + .key = key + }; + UnifiedData data; + UdmfServiceImpl serviceImpl; + auto status = serviceImpl.RetrieveData(option, data); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); +} + +/** +* @tc.name: DeleteData001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, DeleteData001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string intention = DATA_HUB_INTENTION; + auto store = std::make_shared(intention); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + intention.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); + std::string key = "udmf://DataHub/delete.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; + QueryOption option = { + .key = key, + }; + auto record = std::make_shared(); + UnifiedData data; + data.AddRecord(record); + std::vector dataList = { data }; + UdmfServiceImpl serviceImpl; + auto status = serviceImpl.DeleteData(option, dataList); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); +} + +/** +* @tc.name: GetSummary001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetSummary001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string intention = DATA_HUB_INTENTION; + auto store = std::make_shared(intention); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + intention.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); + std::string key = "udmf://DataHub/summary.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; + QueryOption option = { + .key = key, + }; + Summary summary; + UdmfServiceImpl serviceImpl; + auto status = serviceImpl.GetSummary(option, summary); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); +} + +/** +* @tc.name: IsRemoteData001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, IsRemoteData001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string intention = DATA_HUB_INTENTION; + auto store = std::make_shared(intention); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + intention.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); + std::string key = "udmf://DataHub/remote.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; + QueryOption option = { + .key = key, + }; + UdmfServiceImpl serviceImpl; + bool ret = false; + auto status = serviceImpl.IsRemoteData(option, ret); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: GetAppShareOption001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetAppShareOption001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string intention = DATA_HUB_INTENTION; + auto store = std::make_shared(intention); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + intention.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); + UdmfServiceImpl serviceImpl; + int32_t shareOption = CROSS_APP; + auto status = serviceImpl.GetAppShareOption("DataHub", shareOption); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); +} + +/** +* @tc.name: QueryDataCommon001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, QueryDataCommon001, TestSize.Level1) +{ + StoreCache::GetInstance().stores_.Clear(); + std::string intention = DATA_HUB_INTENTION; + auto store = std::make_shared(intention); + store->kvStore_ = std::make_shared(); + int foregroundUserId = 0; + DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + intention.append(std::to_string(foregroundUserId)); + StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); + UdmfServiceImpl serviceImpl; + QueryOption option = { + .intention = Intention::UD_INTENTION_DATA_HUB, + }; + std::vector dataList; + std::shared_ptr store1; + auto status = serviceImpl.QueryDataCommon(option, dataList, store1); + EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); +} + +/** +* @tc.name: PutLocal001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, PutLocal001, TestSize.Level1) +{ + std::string key = "key"; + std::string value = "value"; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->PutLocal(key, value); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} + +/** +* @tc.name: GetLocal001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetLocal001, TestSize.Level1) +{ + std::string key = "key"; + std::string value; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->GetLocal(key, value); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} + +/** +* @tc.name: DeleteLocal001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, DeleteLocal001, TestSize.Level1) +{ + std::string key = "key"; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->DeleteLocal(key); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} + +/** +* @tc.name: PutRuntime001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, PutRuntime001, TestSize.Level1) +{ + std::string key = "key"; + Runtime runtime; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->PutRuntime(key, runtime); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} + +/** +* @tc.name: GetRuntime001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetRuntime001, TestSize.Level1) +{ + std::string key = "key"; + Runtime runtime; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->GetRuntime(key, runtime); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} + +/** +* @tc.name: Update001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, Update001, TestSize.Level1) +{ + UnifiedData data; + auto rumtime = std::make_shared(); + UnifiedKey key(DATA_HUB_INTENTION, "com.demo.test", "111"); + rumtime->key = key; + data.runtime_ = rumtime; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->Update(data); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} + +/** +* @tc.name: Delete001 +* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfServiceImplDbCorruptionMockTest, Delete001, TestSize.Level1) +{ + std::string key = "key"; + auto store = std::make_shared(DATA_HUB_INTENTION); + store->kvStore_ = std::make_shared(); + auto status = store->Delete(key); + EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); +} +}; // namespace DistributedDataTest +}; // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp index 01795f4b1..f2d1b475e 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -737,5 +737,33 @@ HWTEST_F(UdmfRunTimeStoreTest, OnAccountChanged001, TestSize.Level1) SetSelfTokenID(0); observer.OnAccountChanged(eventInfo, 0); } + +/** +* @tc.name: MarkWhenCorrupted001 +* @tc.desc: Normal testcase of MarkWhenCorrupted +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted001, TestSize.Level1) +{ + DistributedDB::DBStatus status = DistributedDB::DBStatus::OK; + auto store = std::make_shared(STORE_ID); + store->MarkWhenCorrupted(status); + EXPECT_FALSE(store->isCorrupted); +} + +/** +* @tc.name: MarkWhenCorrupted001 +* @tc.desc: Normal testcase of MarkWhenCorrupted +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted002, TestSize.Level1) +{ + DistributedDB::DBStatus status = DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; + auto store = std::make_shared(STORE_ID); + store->MarkWhenCorrupted(status); + EXPECT_TRUE(store->isCorrupted); +} }; // namespace DistributedDataTest }; // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp index 0bad354cb..df0427031 100644 --- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp @@ -588,5 +588,39 @@ HWTEST_F(UdmfServiceImplTest, ValidateAndProcessRuntimeData004, TestSize.Level1) int32_t result = impl.ValidateAndProcessRuntimeData(dataSet, runtime, unifiedDataSet, query, deleteKeys); EXPECT_EQ(result, UDMF::E_OK); } + +/** + * @tc.name: CloseStoreWhenCorrupted001 + * @tc.desc: Normal test of CloseStoreWhenCorrupted + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted001, TestSize.Level1) +{ + std::string intention = "drag"; + StoreCache::GetInstance().CloseStores(); + auto store = StoreCache::GetInstance().GetStore(intention); + EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); + Status status = UDMF::E_OK; + UdmfServiceImpl impl; + impl.CloseStoreWhenCorrupted(intention, status); + EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); +} + +/** + * @tc.name: CloseStoreWhenCorrupted002 + * @tc.desc: Abnormal test of CloseStoreWhenCorrupted + * @tc.type: FUNC + */ +HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted002, TestSize.Level1) +{ + std::string intention = "drag"; + StoreCache::GetInstance().CloseStores(); + auto store = StoreCache::GetInstance().GetStore(intention); + EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); + Status status = UDMF::E_DB_CORRUPTED; + UdmfServiceImpl impl; + impl.CloseStoreWhenCorrupted(intention, status); + EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 0); +} }; // namespace DistributedDataTest }; // namespace OHOS::Test diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index e218e7b1f..6b54d02a9 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -60,7 +60,7 @@ Status RuntimeStore::PutLocal(const std::string &key, const std::string &value) auto status = kvStore_->PutLocal(keyBytes, valueBytes); if (status != DBStatus::OK) { ZLOGE("KvStore PutLocal failed, status: %{public}d.", status); - return E_DB_ERROR; + return MarkWhenCorrupted(status); } return E_OK; } @@ -73,7 +73,7 @@ Status RuntimeStore::GetLocal(const std::string &key, std::string &value) DBStatus status = kvStore_->GetLocal(keyBytes, valueBytes); if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { ZLOGE("GetLocal entry failed, key: %{public}s.", key.c_str()); - return E_DB_ERROR; + return MarkWhenCorrupted(status); } if (valueBytes.empty()) { ZLOGW("GetLocal entry is empty, key: %{public}s", key.c_str()); @@ -91,7 +91,7 @@ Status RuntimeStore::DeleteLocal(const std::string &key) DBStatus status = kvStore_->DeleteLocal(keyBytes); if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { ZLOGE("DeleteLocal failed, key: %{public}s.", key.c_str()); - return E_DB_ERROR; + return MarkWhenCorrupted(status); } return E_OK; } @@ -115,9 +115,10 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) { UpdateTime(); std::vector entries; - if (GetEntries(UnifiedKey(key).GetKeyCommonPrefix(), entries) != E_OK) { + auto status = GetEntries(UnifiedKey(key).GetKeyCommonPrefix(), entries); + if (status != E_OK) { ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); - return E_DB_ERROR; + return status; } if (entries.empty()) { ZLOGW("entries is empty, dataPrefix: %{public}s", key.c_str()); @@ -173,9 +174,10 @@ Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) ZLOGW("Get stored summary failed, key: %{public}s, status:%{public}d", summaryKey.c_str(), res); UnifiedData unifiedData; auto udKey = key.GetUnifiedKey(); - if (Get(udKey, unifiedData) != E_OK) { + auto status = Get(udKey, unifiedData); + if (status != E_OK) { ZLOGE("Get unified data failed, key: %{public}s", udKey.c_str()); - return E_DB_ERROR; + return status; } UDDetails details {}; if (PreProcessUtils::GetDetailsFromUData(unifiedData, details)) { @@ -204,7 +206,7 @@ Status RuntimeStore::PutRuntime(const std::string &key, const Runtime &runtime) auto res = kvStore_->Put({key.begin(), key.end()}, value); if (res != OK) { ZLOGE("Put failed, key:%{public}s, status:%{public}d", key.c_str(), res); - return E_DB_ERROR; + return MarkWhenCorrupted(res); } return E_OK; } @@ -220,7 +222,7 @@ Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) } if (res != OK || value.empty()) { ZLOGE("Get failed, key: %{public}s, status:%{public}d", key.c_str(), res); - return E_DB_ERROR; + return MarkWhenCorrupted(res); } auto status = DataHandler::UnmarshalEntries(value, runtime, TAG::TAG_RUNTIME); if (status != E_OK) { @@ -233,14 +235,16 @@ Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) Status RuntimeStore::Update(const UnifiedData &unifiedData) { std::string key = unifiedData.GetRuntime()->key.key; - if (Delete(UnifiedKey(key).GetKeyCommonPrefix()) != E_OK) { + auto status = Delete(UnifiedKey(key).GetKeyCommonPrefix()); + if (status != E_OK) { UpdateTime(); ZLOGE("Delete unified data failed, dataPrefix: %{public}s.", key.c_str()); - return E_DB_ERROR; + return status; } - if (Put(unifiedData) != E_OK) { + status = Put(unifiedData); + if (status != E_OK) { ZLOGE("Update unified data failed, dataPrefix: %{public}s.", key.c_str()); - return E_DB_ERROR; + return status; } return E_OK; } @@ -248,9 +252,10 @@ Status RuntimeStore::Update(const UnifiedData &unifiedData) Status RuntimeStore::Delete(const std::string &key) { std::vector entries; - if (GetEntries(key, entries) != E_OK) { + auto status = GetEntries(key, entries); + if (status != E_OK) { ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); - return E_DB_ERROR; + return status; } if (entries.empty()) { ZLOGD("entries is empty."); @@ -382,7 +387,7 @@ Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector(status)); + if (delegateManager_->DeleteKvStore(storeId_) != DBStatus::OK) { + ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(status)); + } + return false; + } if (status != DBStatus::OK) { ZLOGE("GetKvStore fail, status: %{public}d.", static_cast(status)); return false; @@ -442,6 +454,13 @@ bool RuntimeStore::Init() if (retStatus != DBStatus::OK) { ZLOGE("CloseKvStore fail, status: %{public}d.", static_cast(retStatus)); } + if (isCorrupted) { + ZLOGI("start to delete runtime kvStore."); + retStatus = delegateManager_->DeleteKvStore(storeId_); + if (retStatus != DBStatus::OK) { + ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(retStatus)); + } + } }; kvStore_ = std::shared_ptr(delegate, release); uint32_t pragmData = 16 * 1024 * 1024; @@ -549,7 +568,7 @@ Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vectorGetEntries(dbQuery, entries); if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { ZLOGE("KvStore getEntries failed, status: %{public}d.", static_cast(status)); - return E_DB_ERROR; + return MarkWhenCorrupted(status); } return E_OK; } @@ -559,7 +578,7 @@ Status RuntimeStore::PutEntries(const std::vector &entries) DBStatus status = kvStore_->PutBatch(entries); if (status != DBStatus::OK) { ZLOGE("putBatch failed, status: %{public}d.", status); - return E_DB_ERROR; + return MarkWhenCorrupted(status); } return E_OK; } @@ -569,10 +588,19 @@ Status RuntimeStore::DeleteEntries(const std::vector &keys) DBStatus status = kvStore_->DeleteBatch(keys); if (status != DBStatus::OK) { ZLOGE("deleteBatch failed, status: %{public}d.", status); - return E_DB_ERROR; + return MarkWhenCorrupted(status); } return E_OK; } +Status RuntimeStore::MarkWhenCorrupted(DistributedDB::DBStatus status) +{ + if (status == INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("Kv database corrupted"); + isCorrupted = true; + return E_DB_CORRUPTED; + } + return E_DB_ERROR; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h index d5f4be1a8..421151f80 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -64,6 +64,9 @@ private: void NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, const DevNameMap &deviceNameMap); Status PutSummary(const UnifiedData &data, std::vector &entries); + Status MarkWhenCorrupted(DistributedDB::DBStatus status); + bool isCorrupted = false; + }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp index 545b549a1..30ae5c7a1 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -38,7 +38,6 @@ std::shared_ptr StoreCache::GetStore(std::string intention) } std::string key = intention; key.append(std::to_string(foregroundUserId)); - stores_.Compute(key, [&store, intention](const auto &key, std::shared_ptr &storePtr) -> bool { if (storePtr != nullptr) { store = storePtr; @@ -56,7 +55,6 @@ std::shared_ptr StoreCache::GetStore(std::string intention) } return false; }); - std::unique_lock lock(taskMutex_); if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) { taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); @@ -94,6 +92,19 @@ void StoreCache::CloseStores() stores_.Clear(); } +void StoreCache::RemoveStore(std::string intention) +{ + ZLOGI("RemoveStore, intention:%{public}s", intention.c_str()); + int foregroundUserId = 0; + if (!DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId)) { + ZLOGE("QueryForegroundUserId failed."); + return; + } + std::string key = intention; + key.append(std::to_string(foregroundUserId)); + stores_.Erase(key); +} + bool StoreCache::IsValidIntention(const std::string &intention) { return UnifiedDataUtils::GetIntentionByString(intention) != UD_INTENTION_BUTT; diff --git a/services/distributeddataservice/service/udmf/store/store_cache.h b/services/distributeddataservice/service/udmf/store/store_cache.h index 5d3918d2d..b71481dbe 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.h +++ b/services/distributeddataservice/service/udmf/store/store_cache.h @@ -28,6 +28,7 @@ public: static StoreCache &GetInstance(); void SetThreadPool(std::shared_ptr executors); void CloseStores(); + void RemoveStore(std::string intention); private: StoreCache() {} diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index bade1ef4f..9c8bc2e4a 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -128,18 +128,15 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData ZLOGE("UnifiedData is invalid."); return E_INVALID_PARAMETERS; } - if (!UnifiedDataUtils::IsValidIntention(option.intention)) { ZLOGE("Invalid parameters intention: %{public}d.", option.intention); return E_INVALID_PARAMETERS; } - // imput runtime info before put it into store and save one privilege if (PreProcessUtils::FillRuntimeInfo(unifiedData, option) != E_OK) { ZLOGE("Imputation failed"); return E_ERROR; } - std::string intention = unifiedData.GetRuntime()->key.intention; if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); @@ -155,9 +152,10 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData ZLOGE("Get store failed:%{public}s", intention.c_str()); return E_DB_ERROR; } - - if (store->Put(unifiedData) != E_OK) { - ZLOGE("Put unified data failed:%{public}s", intention.c_str()); + auto status = store->Put(unifiedData); + if (status != E_OK) { + ZLOGE("Put unified data failed:%{public}s, status:%{public}d", intention.c_str(), status); + CloseStoreWhenCorrupted(intention, status); return E_DB_ERROR; } key = unifiedData.GetRuntime()->key.GetUnifiedKey(); @@ -223,7 +221,8 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni int32_t res = store->Get(query.key, unifiedData); if (res != E_OK) { ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str()); - return res; + CloseStoreWhenCorrupted(key.intention, static_cast(res)); + return E_DB_ERROR; } if (!unifiedData.IsComplete()) { @@ -420,6 +419,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi int32_t res = store->Get(query.key, data); if (res != E_OK) { ZLOGE("Get data failed:%{public}s", key.intention.c_str()); + CloseStoreWhenCorrupted(key.intention, static_cast(res)); return res; } if (data.IsEmpty()) { @@ -440,8 +440,10 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); unifiedData.SetRuntime(*runtime); PreProcessUtils::SetRecordUid(unifiedData); - if (store->Update(unifiedData) != E_OK) { + res = store->Update(unifiedData); + if (res != E_OK) { ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); + CloseStoreWhenCorrupted(key.intention, static_cast(res)); return E_DB_ERROR; } return E_OK; @@ -480,7 +482,8 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector(status)); + return E_DB_ERROR; } if (dataSet.empty()) { ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); @@ -498,8 +501,10 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorDeleteBatch(deleteKeys) != E_OK) { + status = store->DeleteBatch(deleteKeys); + if (status != E_OK) { ZLOGE("Remove data failed."); + CloseStoreWhenCorrupted(key.intention, static_cast(status)); return E_DB_ERROR; } return E_OK; @@ -551,9 +556,10 @@ int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) ZLOGE("Get store failed:%{public}s", key.intention.c_str()); return E_DB_ERROR; } - - if (store->GetSummary(key, summary) != E_OK) { + auto status = store->GetSummary(key, summary); + if (status != E_OK) { ZLOGE("Store get summary failed:%{public}s", key.intention.c_str()); + CloseStoreWhenCorrupted(key.intention, status); return E_DB_ERROR; } return E_OK; @@ -598,14 +604,17 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi } if (res != E_OK) { ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); + CloseStoreWhenCorrupted(key.intention, res); return res; } runtime.privileges.emplace_back(privilege); res = store->PutRuntime(query.key, runtime); if (res != E_OK) { ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); + CloseStoreWhenCorrupted(key.intention, res); + return E_DB_ERROR; } - return res; + return E_OK; } int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) @@ -715,6 +724,7 @@ int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result) auto res = store->GetRuntime(query.key, runtime); if (res != E_OK) { ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); + CloseStoreWhenCorrupted(key.intention, res); return E_DB_ERROR; } @@ -751,9 +761,10 @@ int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t ZLOGE("SetAppShareOption failed,shareOption already set:%{public}s", shareOptionTmp.c_str()); return E_SETTINGS_EXISTED; } - - if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) { - ZLOGE("Store get unifiedData failed:%{public}d", shareOption); + auto status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)); + if (status != E_OK) { + ZLOGE("Store get unifiedData failed:%{public}d", status); + CloseStoreWhenCorrupted(intention, status); return E_DB_ERROR; } return E_OK; @@ -775,7 +786,8 @@ int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); if (ret != E_OK) { ZLOGW("GetLocal failed:%{public}s", intention.c_str()); - return ret; + CloseStoreWhenCorrupted(intention, static_cast(ret)); + return E_DB_ERROR; } ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str()); shareOption = ShareOptionsUtil::GetEnumNum(appShareOption); @@ -802,8 +814,10 @@ int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) } UnifiedData unifiedData; - if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) { - ZLOGE("Store DeleteLocal failed:%{public}s", intention.c_str()); + auto status = store->DeleteLocal(std::to_string(accessTokenIDEx)); + if (status != E_OK) { + ZLOGE("Store DeleteLocal failed:%{public}s, status:%{public}d", intention.c_str(), status); + CloseStoreWhenCorrupted(intention, status); return E_DB_ERROR; } return E_OK; @@ -849,8 +863,10 @@ int32_t UdmfServiceImpl::QueryDataCommon( ZLOGE("Get store failed:%{public}s", intention.c_str()); return E_DB_ERROR; } - if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { - ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); + auto status = store->GetBatchData(dataPrefix, dataSet); + if (status != E_OK) { + ZLOGE("Get dataSet failed, dataPrefix: %{public}s, status:%{public}d.", dataPrefix.c_str(), status); + CloseStoreWhenCorrupted(intention, status); return E_DB_ERROR; } return E_OK; @@ -1135,8 +1151,10 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptrPutSummary(udkey, summary) != E_OK) { - ZLOGE("Put summary failed:%{public}s", key.c_str()); + auto status = store->PutSummary(udkey, summary); + if (status != E_OK) { + ZLOGE("Put summary failed:%{public}s, status:%{public}d", key.c_str(), status); + CloseStoreWhenCorrupted(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status); return E_DB_ERROR; } return E_OK; @@ -1239,5 +1257,13 @@ bool UdmfServiceImpl::IsValidInput(const QueryOption &query, UnifiedData &unifie } return true; } + +void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, Status status) +{ + if (status == E_DB_CORRUPTED) { + ZLOGE("Kv database corrupted, start to remove store"); + StoreCache::GetInstance().RemoveStore(intention); + } +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index b728d8199..f8aed0684 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -83,6 +83,7 @@ private: int32_t ValidateAndProcessRuntimeData(const std::vector &dataSet, std::shared_ptr runtime, std::vector &unifiedDataSet, const QueryOption &query, std::vector &deleteKeys); int32_t CheckAppId(std::shared_ptr runtime, const std::string &bundleName); + void CloseStoreWhenCorrupted(const std::string &intention, Status status); class Factory { public: Factory(); -- Gitee From 29eeb28287329921dd350553efdfb6d79e47fd80 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 17:39:31 +0800 Subject: [PATCH 02/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: Ia40451705664dbb9c6539d1b5cb0288aac352326 --- 3178.diff.txt | 1798 ----------------- .../service/test/BUILD.gn | 28 +- 2 files changed, 14 insertions(+), 1812 deletions(-) delete mode 100644 3178.diff.txt diff --git a/3178.diff.txt b/3178.diff.txt deleted file mode 100644 index d941b6552..000000000 --- a/3178.diff.txt +++ /dev/null @@ -1,1798 +0,0 @@ -diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn -index c46be02227591b1f6b100bf30c6d7e901a3bb939..a4956c0691685940861d91b2951bf2173b8f9efd 100644 ---- a/services/distributeddataservice/service/test/BUILD.gn -+++ b/services/distributeddataservice/service/test/BUILD.gn -@@ -2105,6 +2105,94 @@ ohos_unittest("BackupManagerServiceTest") { - ] - } - -+ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { -+ module_out_path = module_output_path -+ sanitize = { -+ cfi = true -+ cfi_cross_dso = true -+ debug = false -+ blocklist = "${datamgr_service_path}/cfi_blocklist.txt" -+ } -+ sources = [ -+ "udmf_db_corruption_mock_test.cpp", -+ "mock/kv_store_nb_delegate_corruption_mock.cpp", -+ "mock/preprocess_utils_mock.cpp", -+ "${data_service_path}/service/udmf/udmf_service_impl.cpp", -+ "${data_service_path}/service/udmf/lifecycle/clean_on_startup.cpp", -+ "${data_service_path}/service/udmf/lifecycle/clean_on_timeout.cpp", -+ "${data_service_path}/service/udmf/lifecycle/lifecycle_manager.cpp", -+ "${data_service_path}/service/udmf/lifecycle/lifecycle_policy.cpp", -+ "${data_service_path}/service/udmf/permission/checker_manager.cpp", -+ "${data_service_path}/service/udmf/permission/data_checker.cpp", -+ "${data_service_path}/service/udmf/permission/uri_permission_manager.cpp", -+ "${data_service_path}/service/udmf/preprocess/data_handler.cpp", -+ "${data_service_path}/service/udmf/preprocess/udmf_notifier_proxy.cpp", -+ "${data_service_path}/service/udmf/store/runtime_store.cpp", -+ "${data_service_path}/service/udmf/store/store_account_observer.cpp", -+ "${data_service_path}/service/udmf/store/store_cache.cpp", -+ "${data_service_path}/service/udmf/udmf_service_stub.cpp", -+ "${data_service_path}/app/src/kvstore_meta_manager.cpp", -+ ] -+ -+ include_dirs = [ -+ "${data_service_path}/adapter/include/account", -+ "${data_service_path}/adapter/include/communicator", -+ "${data_service_path}/app/src", -+ "${data_service_path}/service/kvdb", -+ "${data_service_path}/service/matrix/include", -+ "${data_service_path}/service/udmf", -+ "${data_service_path}/service/udmf/store", -+ "${data_service_path}/service/udmf/preprocess", -+ "${data_service_path}/service/udmf/permission", -+ "${data_service_path}/service/test/mock", -+ ] -+ -+ configs = [ ":module_private_config" ] -+ -+ external_deps = [ -+ "ability_base:base", -+ "ability_base:zuri", -+ "ability_base:want", -+ "ability_runtime:uri_permission_mgr", -+ "access_token:libaccesstoken_sdk", -+ "access_token:libnativetoken_shared", -+ "access_token:libtoken_setproc", -+ "access_token:libtokenid_sdk", -+ "app_file_service:remote_file_share_native", -+ "bundle_framework:appexecfwk_base", -+ "bundle_framework:appexecfwk_core", -+ "device_manager:devicemanagersdk", -+ "dfs_service:distributed_file_daemon_kit_inner", -+ "hilog:libhilog", -+ "hisysevent:libhisysevent", -+ "hitrace:hitrace_meter", -+ "hitrace:libhitracechain", -+ "ipc:ipc_core", -+ "kv_store:distributeddata_inner", -+ "kv_store:distributeddb", -+ "kv_store:distributeddata_mgr", -+ "udmf:udmf_client", -+ "udmf:utd_client", -+ "dsoftbus:softbus_client", -+ "samgr:samgr_proxy", -+ "safwk:system_ability_fwk", -+ "openssl:libcrypto_shared", -+ "googletest:gmock_main", -+ "googletest:gtest_main", -+ "dataclassification:data_transit_mgr", -+ ] -+ -+ deps = [ -+ "${data_service_path}/framework:distributeddatasvcfwk", -+ "${data_service_path}/service:distributeddatasvc", -+ ] -+ -+ defines = [ -+ "private=public", -+ "protected=public", -+ ] -+} -+ - ############################################################################### - group("unittest") { - testonly = true -@@ -2133,6 +2221,7 @@ group("unittest") { - ":UdmfRunTimeStoreTest", - ":UdmfServiceImplMockTest", - ":UdmfServiceImplTest", -+ ":UdmfServiceImplDbCorruptionMockTest", - ":UdmfServiceStubMockTest", - ":UdmfServiceStubTest", - ] -diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..04a12f2a08f1d7370388f9c7434bc28c3d4bdb37 ---- /dev/null -+++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp -@@ -0,0 +1,345 @@ -+/* -+ * Copyright (c) 2024 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 "kv_store_nb_delegate_corruption_mock.h" -+ -+#include "store_types.h" -+namespace DistributedDB { -+DBStatus KvStoreNbDelegateCorruptionMock::Get(const Key &key, Value &value) const -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, std::vector &entries) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, std::vector &entries) const -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, KvStoreResultSet *&resultSet) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetCount(const Query &query, int &count) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::CloseResultSet(KvStoreResultSet *&resultSet) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Put(const Key &key, const Value &value) -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::PutBatch(const std::vector &entries) -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::DeleteBatch(const std::vector &keys) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Delete(const Key &key) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetLocal(const Key &key, Value &value) const -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetLocalEntries(const Key &keyPrefix, std::vector &entries) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::PutLocal(const Key &key, const Value &value) -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocal(const Key &key) -+{ -+ return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, -+ const KvStoreNbPublishOnConflict &onConflict) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::RegisterObserver(const Key &key, unsigned int mode, -+ KvStoreObserver *observer) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::UnRegisterObserver(const KvStoreObserver *observer) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device) -+{ -+ return DBStatus::OK; -+} -+ -+std::string KvStoreNbDelegateCorruptionMock::GetStoreId() const -+{ -+ return "ok"; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, -+ const std::function &devicesMap)> &onComplete, -+ bool wait) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Pragma(PragmaCmd cmd, PragmaData ¶mData) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetConflictNotifier(int conflictType, -+ const KvStoreNbConflictNotifier ¬ifier) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Rekey(const CipherPassword &password) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Export(const std::string &filePath, -+ const CipherPassword &passwd, bool force) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Import(const std::string &filePath, const CipherPassword &passwd, -+ bool isNeedIntegrityCheck) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::StartTransaction() -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Commit() -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Rollback() -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::PutLocalBatch(const std::vector &entries) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocalBatch(const std::vector &keys) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetSecurityOption(SecurityOption &option) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, -+ const std::function &devicesMap)> &onComplete, -+ const Query &query, bool wait) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::CheckIntegrity() const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetEqualIdentifier(const std::string &identifier, -+ const std::vector &targets) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetPushDataInterceptor(const PushDataInterceptor &interceptor) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SubscribeRemoteQuery(const std::vector &devices, -+ const std::function &devicesMap)> &onComplete, -+ const Query &query, bool wait) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::UnSubscribeRemoteQuery(const std::vector &devices, -+ const std::function &devicesMap)> &onComplete, -+ const Query &query, bool wait) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData() -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetKeys(const Key &keyPrefix, std::vector &keys) const -+{ -+ return DBStatus::OK; -+} -+ -+size_t KvStoreNbDelegateCorruptionMock::GetSyncDataSize(const std::string &device) const -+{ -+ size_t size = 0; -+ return size; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::UpdateKey(const UpdateKeyCallback &callback) -+{ -+ return DBStatus::OK; -+} -+ -+std::pair KvStoreNbDelegateCorruptionMock::GetWatermarkInfo(const std::string &device) -+{ -+ std::pair ret; -+ return ret; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDB(const std::map> &cloudDBs) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDbSchema(const std::map &schema) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, ClearMode mode) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) -+{ -+ return DBStatus::OK; -+} -+ -+int32_t KvStoreNbDelegateCorruptionMock::GetTaskCount() -+{ -+ int32_t taskCount = taskCountMock_; -+ return taskCount; -+} -+ -+void KvStoreNbDelegateCorruptionMock::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) -+{ -+ auto callback_ = callback; -+} -+ -+std::pair> KvStoreNbDelegateCorruptionMock::GetCloudVersion( -+ const std::string &device) -+{ -+ if (device.empty()) { -+ return { DBStatus::OK, {} }; -+ } else if (device == "test") { -+ return { DBStatus::DB_ERROR, {} }; -+ } else if (device == "device") { -+ return { DBStatus::DB_ERROR, {{device, device}} }; -+ } else { -+ return { DBStatus::OK, {{device, device}} }; -+ } -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::SetCloudSyncConfig(const CloudSyncConfig &config) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::GetDeviceEntries(const std::string &device, std::vector &entries) const -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) -+{ -+ return DBStatus::OK; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::CancelSync(uint32_t syncId) -+{ -+ return DBStatus::OK; -+} -+ -+KvStoreNbDelegate::DatabaseStatus KvStoreNbDelegateCorruptionMock::GetDatabaseStatus() const -+{ -+ return {}; -+} -+ -+DBStatus KvStoreNbDelegateCorruptionMock::ClearMetaData(ClearKvMetaDataOption option) -+{ -+ return DBStatus::OK; -+} -+} // namespace DistributedDB -\ No newline at end of file -diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h -new file mode 100644 -index 0000000000000000000000000000000000000000..16176d2a3f1d3ef9e4db2addc824136697bda937 ---- /dev/null -+++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h -@@ -0,0 +1,113 @@ -+/* -+ * Copyright (c) 2021 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 KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK -+#define KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK -+ -+#include -+#include -+#include -+ -+#include "cloud/cloud_store_types.h" -+#include "cloud/icloud_db.h" -+#include "intercepted_data.h" -+#include "iprocess_system_api_adapter.h" -+#include "kv_store_nb_conflict_data.h" -+#include "kv_store_nb_delegate.h" -+#include "kv_store_observer.h" -+#include "kv_store_result_set.h" -+#include "query.h" -+#include "store_types.h" -+ -+namespace DistributedDB { -+class KvStoreNbDelegateCorruptionMock : public DistributedDB::KvStoreNbDelegate { -+public: -+ int32_t taskCountMock_ = 0; -+ ~KvStoreNbDelegateCorruptionMock() = default; -+ DBStatus Get(const Key &key, Value &value) const; -+ DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const; -+ DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const; -+ DBStatus GetEntries(const Query &query, std::vector &entries) const; -+ DBStatus GetEntries(const Query &query, KvStoreResultSet *&resultSet) const; -+ DBStatus GetCount(const Query &query, int &count) const; -+ DBStatus CloseResultSet(KvStoreResultSet *&resultSet); -+ DBStatus Put(const Key &key, const Value &value); -+ DBStatus PutBatch(const std::vector &entries); -+ DBStatus DeleteBatch(const std::vector &keys); -+ DBStatus Delete(const Key &key); -+ DBStatus GetLocal(const Key &key, Value &value) const; -+ DBStatus GetLocalEntries(const Key &keyPrefix, std::vector &entries) const; -+ DBStatus PutLocal(const Key &key, const Value &value); -+ DBStatus DeleteLocal(const Key &key); -+ DBStatus PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, -+ const KvStoreNbPublishOnConflict &onConflict); -+ DBStatus UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp); -+ DBStatus RegisterObserver(const Key &key, unsigned int mode, KvStoreObserver *observer); -+ DBStatus UnRegisterObserver(const KvStoreObserver *observer); -+ DBStatus RemoveDeviceData(const std::string &device); -+ std::string GetStoreId() const; -+ DBStatus Sync(const std::vector &devices, SyncMode mode, -+ const std::function &devicesMap)> &onComplete, -+ bool wait = false); -+ DBStatus Pragma(PragmaCmd cmd, PragmaData ¶mData); -+ DBStatus SetConflictNotifier(int conflictType, -+ const KvStoreNbConflictNotifier ¬ifier); -+ DBStatus Rekey(const CipherPassword &password); -+ DBStatus Export(const std::string &filePath, const CipherPassword &passwd, bool force = false); -+ DBStatus Import(const std::string &filePath, const CipherPassword &passwd, bool isNeedIntegrityCheck = false); -+ DBStatus StartTransaction(); -+ DBStatus Commit(); -+ DBStatus Rollback(); -+ DBStatus PutLocalBatch(const std::vector &entries); -+ DBStatus DeleteLocalBatch(const std::vector &keys); -+ DBStatus GetSecurityOption(SecurityOption &option) const; -+ DBStatus SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier); -+ DBStatus Sync(const std::vector &devices, SyncMode mode, -+ const std::function &devicesMap)> &onComplete, -+ const Query &query, bool wait); -+ DBStatus CheckIntegrity() const; -+ DBStatus SetEqualIdentifier(const std::string &identifier, -+ const std::vector &targets); -+ DBStatus SetPushDataInterceptor(const PushDataInterceptor &interceptor); -+ DBStatus SubscribeRemoteQuery(const std::vector &devices, -+ const std::function &devicesMap)> &onComplete, -+ const Query &query, bool wait); -+ DBStatus UnSubscribeRemoteQuery(const std::vector &devices, -+ const std::function &devicesMap)> &onComplete, -+ const Query &query, bool wait); -+ DBStatus RemoveDeviceData(); -+ DBStatus GetKeys(const Key &keyPrefix, std::vector &keys) const; -+ size_t GetSyncDataSize(const std::string &device) const; -+ DBStatus UpdateKey(const UpdateKeyCallback &callback); -+ std::pair GetWatermarkInfo(const std::string &device); -+ DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess); -+ DBStatus SetCloudDB(const std::map> &cloudDBs); -+ DBStatus SetCloudDbSchema(const std::map &schema); -+ DBStatus RemoveDeviceData(const std::string &device, ClearMode mode); -+ DBStatus RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode); -+ int32_t GetTaskCount(); -+ void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback); -+ std::pair> GetCloudVersion( -+ const std::string &device); -+ DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor); -+ DBStatus SetCloudSyncConfig(const CloudSyncConfig &config); -+ DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const; -+ DBStatus Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess); -+ DBStatus CancelSync(uint32_t syncId); -+ DatabaseStatus GetDatabaseStatus() const; -+ DBStatus ClearMetaData(ClearKvMetaDataOption option); -+}; -+} // namespace DistributedDB -+#endif // KV_STORE_NB_DELEGATE_CORRUPTION_H_MOCK -\ No newline at end of file -diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..af03ce4d651ba2a21c1024a9b192d504a570dd8b ---- /dev/null -+++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp -@@ -0,0 +1,204 @@ -+/* -+ * 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. -+ */ -+#define LOG_TAG "PreProcessUtils" -+ -+#include "preprocess_utils.h" -+ -+#include "bundle_info.h" -+#include "dds_trace.h" -+#include "udmf_radar_reporter.h" -+#include "accesstoken_kit.h" -+#include "device_manager_adapter.h" -+#include "file_mount_manager.h" -+#include "iservice_registry.h" -+#include "log_print.h" -+#include "system_ability_definition.h" -+#include "udmf_radar_reporter.h" -+#include "udmf_utils.h" -+#include "utils/crypto.h" -+#include "uri_permission_manager_client.h" -+#include "ipc_skeleton.h" -+#include "bundle_mgr_interface.h" -+namespace OHOS { -+namespace UDMF { -+using namespace OHOS::DistributedDataDfx; -+using namespace Security::AccessToken; -+using namespace OHOS::AppFileService::ModuleRemoteFileShare; -+using namespace RadarReporter; -+ -+int32_t PreProcessUtils::FillRuntimeInfo(UnifiedData &data, CustomOption &option) -+{ -+ auto it = UD_INTENTION_MAP.find(option.intention); -+ if (it == UD_INTENTION_MAP.end()) { -+ return E_ERROR; -+ } -+ std::string bundleName = "bundleName"; -+ std::string intention = it->second; -+ UnifiedKey key(intention, bundleName, GenerateId()); -+ Privilege privilege; -+ privilege.tokenId = option.tokenId; -+ -+ Runtime runtime; -+ runtime.key = key; -+ runtime.privileges.emplace_back(privilege); -+ runtime.createTime = GetTimestamp(); -+ runtime.sourcePackage = bundleName; -+ runtime.createPackage = bundleName; -+ runtime.recordTotalNum = static_cast(data.GetRecords().size()); -+ runtime.tokenId = option.tokenId; -+ runtime.visibility = option.visibility; -+ runtime.appId = "appId"; -+ data.SetRuntime(runtime); -+ return E_OK; -+} -+ -+std::string PreProcessUtils::GenerateId() -+{ -+ return "1122ac"; -+} -+ -+time_t PreProcessUtils::GetTimestamp() -+{ -+ std::chrono::time_point tp = -+ std::chrono::time_point_cast(std::chrono::system_clock::now()); -+ time_t timestamp = tp.time_since_epoch().count(); -+ return timestamp; -+} -+ -+int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId, int &userId) -+{ -+ userId = 100; -+ return E_OK; -+} -+ -+bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleName) -+{ -+ bundleName = "processName"; -+ return true; -+ -+} -+ -+bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName) -+{ -+ processName = "processName"; -+ return true; -+} -+ -+std::string PreProcessUtils::GetAppId(const std::string &bundleName) -+{ -+ return "com.demo.test"; -+} -+ -+std::string PreProcessUtils::GetLocalDeviceId() -+{ -+ return "123"; -+} -+ -+void PreProcessUtils::SetRemoteData(UnifiedData &data) -+{ -+ return; -+} -+ -+int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) -+{ -+ return E_OK; -+} -+ -+bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex) -+{ -+ return true; -+} -+ -+bool PreProcessUtils::IsNetworkingEnabled() -+{ -+ return true; -+} -+ -+void PreProcessUtils::ProcessFileType(std::vector> records, -+ std::function)> callback) -+{ -+ return; -+} -+ -+void PreProcessUtils::ProcessRecord(std::shared_ptr record, uint32_t tokenId, -+ bool isLocal, std::vector &uris) -+{ -+ return; -+} -+ -+void PreProcessUtils::GetHtmlFileUris(uint32_t tokenId, UnifiedData &data, -+ bool isLocal, std::vector &uris) -+{ -+ return; -+} -+ -+void PreProcessUtils::ClearHtmlDfsUris(UnifiedData &data) -+{ -+ return; -+} -+ -+void PreProcessUtils::ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris) -+{ -+ return; -+} -+ -+void PreProcessUtils::SetRecordUid(UnifiedData &data) -+{ -+ return; -+} -+ -+bool PreProcessUtils::GetDetailsFromUData(const UnifiedData &data, UDDetails &details) -+{ -+ return true; -+} -+ -+Status PreProcessUtils::GetSummaryFromDetails(const UDDetails &details, Summary &summary) -+{ -+ return E_OK; -+} -+ -+sptr PreProcessUtils::GetBundleMgr() -+{ -+ auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); -+ if (samgrProxy == nullptr) { -+ ZLOGE("Failed to get system ability mgr."); -+ return nullptr; -+ } -+ auto bundleMgrProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); -+ if (bundleMgrProxy == nullptr) { -+ ZLOGE("Failed to Get BMS SA."); -+ return nullptr; -+ } -+ auto bundleManager = iface_cast(bundleMgrProxy); -+ if (bundleManager == nullptr) { -+ ZLOGE("Failed to get bundle manager"); -+ return nullptr; -+ } -+ return bundleManager; -+} -+ -+bool PreProcessUtils::GetSpecificBundleName(const std::string &bundleName, int32_t appIndex, -+ std::string &specificBundleName) -+{ -+ return true; -+} -+ -+bool PreProcessUtils::GetSpecificBundleNameByTokenId(uint32_t tokenId, std::string &bundleName) -+{ -+ bundleName = "bundleName"; -+ return true; -+} -+} // namespace UDMF -+} // namespace OHOS -\ No newline at end of file -diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h -new file mode 100644 -index 0000000000000000000000000000000000000000..c13e8590bbd7275a769c0de184eb22f270853a77 ---- /dev/null -+++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h -@@ -0,0 +1,52 @@ -+/* -+ * 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. -+ */ -+#ifndef UDMF_PREPROCESS_UTILS_H -+#define UDMF_PREPROCESS_UTILS_H -+ -+#include "bundlemgr/bundle_mgr_proxy.h" -+#include "unified_data.h" -+ -+namespace OHOS { -+namespace UDMF { -+class PreProcessUtils { -+public: -+ static int32_t FillRuntimeInfo(UnifiedData &data, CustomOption &option); -+ static std::string GenerateId(); -+ static time_t GetTimestamp(); -+ static int32_t GetHapUidByToken(uint32_t tokenId, int &userId); -+ static bool GetHapBundleNameByToken(int tokenId, std::string &bundleName); -+ static bool GetNativeProcessNameByToken(int tokenId, std::string &processName); -+ static std::string GetLocalDeviceId(); -+ static void SetRemoteData(UnifiedData &data); -+ static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); -+ static bool GetInstIndex(uint32_t tokenId, int32_t &instIndex); -+ static bool IsNetworkingEnabled(); -+ static void ProcessFileType(std::vector> records, -+ std::function)> callback); -+ static void GetHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); -+ static void ClearHtmlDfsUris(UnifiedData &data); -+ static void ProcessHtmlFileUris(uint32_t tokenId, UnifiedData &data, bool isLocal, std::vector &uris); -+ static void ProcessRecord(std::shared_ptr record, uint32_t tokenId, -+ bool isLocal, std::vector &uris); -+ static void SetRecordUid(UnifiedData &data); -+ static bool GetDetailsFromUData(const UnifiedData &data, UDDetails &details); -+ static Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); -+ static bool GetSpecificBundleNameByTokenId(uint32_t tokenId, std::string &bundleName); -+ static std::string GetAppId(const std::string &bundleName); -+ static sptr GetBundleMgr(); -+}; -+} // namespace UDMF -+} // namespace OHOS -+#endif // UDMF_PREPROCESS_UTILS_H -\ No newline at end of file -diff --git a/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp b/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..7d5c7cc94d17191fada5e7ca9550cdbe6bc43b9f ---- /dev/null -+++ b/services/distributeddataservice/service/test/udmf_db_corruption_mock_test.cpp -@@ -0,0 +1,388 @@ -+/* -+* 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. -+*/ -+ -+#include "udmf_service_impl.h" -+ -+#include "accesstoken_kit.h" -+#include "bootstrap.h" -+#include "device_manager_adapter.h" -+#include "executor_pool.h" -+#include "gtest/gtest.h" -+#include "ipc_skeleton.h" -+#include "kvstore_meta_manager.h" -+#include "metadata/meta_data_manager.h" -+#include "nativetoken_kit.h" -+#include "preprocess_utils.h" -+#include "runtime_store.h" -+#include "text.h" -+#include "token_setproc.h" -+#include "runtime_store.h" -+#include "gtest/gtest.h" -+#include "kv_store_nb_delegate_corruption_mock.h" -+#include "account/account_delegate.h" -+ -+using namespace OHOS::UDMF; -+using namespace testing::ext; -+using namespace testing; -+using namespace OHOS::Security::AccessToken; -+using namespace OHOS::UDMF; -+using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; -+namespace OHOS::Test { -+namespace DistributedDataTest { -+constexpr const char *DATA_HUB_INTENTION = "DataHub"; -+class UdmfServiceImplDbCorruptionMockTest : public testing::Test { -+public: -+ static void SetUpTestCase(void); -+ static void TearDownTestCase(void) {}; -+ void SetUp() {}; -+ void TearDown() {}; -+}; -+ -+static void GrantPermissionNative() -+{ -+ const char **perms = new const char *[3]; -+ perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; -+ perms[1] = "ohos.permission.ACCESS_SERVICE_DM"; -+ perms[2] = "ohos.permission.MONITOR_DEVICE_NETWORK_STATE"; // perms[2] is a permission parameter -+ TokenInfoParams infoInstance = { -+ .dcapsNum = 0, -+ .permsNum = 3, -+ .aclsNum = 0, -+ .dcaps = nullptr, -+ .perms = perms, -+ .acls = nullptr, -+ .processName = "distributed_data_test", -+ .aplStr = "system_basic", -+ }; -+ uint64_t tokenId = GetAccessTokenId(&infoInstance); -+ SetSelfTokenID(tokenId); -+ AccessTokenKit::ReloadNativeTokenInfo(); -+ delete[] perms; -+} -+ -+void UdmfServiceImplDbCorruptionMockTest::SetUpTestCase(void) -+{ -+ GrantPermissionNative(); -+ DistributedData::Bootstrap::GetInstance().LoadComponents(); -+ DistributedData::Bootstrap::GetInstance().LoadDirectory(); -+ DistributedData::Bootstrap::GetInstance().LoadCheckers(); -+ size_t max = 2; -+ size_t min = 1; -+ auto executors = std::make_shared(max, min); -+ DmAdapter::GetInstance().Init(executors); -+ DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); -+ DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter(); -+ DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener(); -+} -+ -+/** -+* @tc.name: SaveDataTest001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, SaveDataTest001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string key = DATA_HUB_INTENTION; -+ auto store = std::make_shared(key); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ key.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(key, store); -+ CustomOption option { -+ .intention = Intention::UD_INTENTION_DATA_HUB, -+ .tokenId = 1 -+ }; -+ auto record = std::make_shared(); -+ UnifiedData data; -+ data.AddRecord(record); -+ std::string key1 = "key"; -+ UdmfServiceImpl serviceImpl; -+ auto status = serviceImpl.SaveData(option, data, key1); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+} -+ -+/** -+* @tc.name: RetrieveData001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, RetrieveData001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string intention = "drag"; -+ auto store = std::make_shared(intention); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ intention.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); -+ std::string key = "udmf://drag/get.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; -+ QueryOption option = { -+ .key = key -+ }; -+ UnifiedData data; -+ UdmfServiceImpl serviceImpl; -+ auto status = serviceImpl.RetrieveData(option, data); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+} -+ -+/** -+* @tc.name: DeleteData001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, DeleteData001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string intention = DATA_HUB_INTENTION; -+ auto store = std::make_shared(intention); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ intention.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); -+ std::string key = "udmf://DataHub/delete.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; -+ QueryOption option = { -+ .key = key, -+ }; -+ auto record = std::make_shared(); -+ UnifiedData data; -+ data.AddRecord(record); -+ std::vector dataList = { data }; -+ UdmfServiceImpl serviceImpl; -+ auto status = serviceImpl.DeleteData(option, dataList); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+} -+ -+/** -+* @tc.name: GetSummary001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetSummary001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string intention = DATA_HUB_INTENTION; -+ auto store = std::make_shared(intention); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ intention.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); -+ std::string key = "udmf://DataHub/summary.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; -+ QueryOption option = { -+ .key = key, -+ }; -+ Summary summary; -+ UdmfServiceImpl serviceImpl; -+ auto status = serviceImpl.GetSummary(option, summary); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+} -+ -+/** -+* @tc.name: IsRemoteData001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, IsRemoteData001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string intention = DATA_HUB_INTENTION; -+ auto store = std::make_shared(intention); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ intention.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); -+ std::string key = "udmf://DataHub/remote.example.myapplication/L]WQ=JezoKgDc8\\Rz`q6koADcGRdKMnf"; -+ QueryOption option = { -+ .key = key, -+ }; -+ UdmfServiceImpl serviceImpl; -+ bool ret = false; -+ auto status = serviceImpl.IsRemoteData(option, ret); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+ EXPECT_FALSE(ret); -+} -+ -+/** -+* @tc.name: GetAppShareOption001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetAppShareOption001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string intention = DATA_HUB_INTENTION; -+ auto store = std::make_shared(intention); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ intention.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); -+ UdmfServiceImpl serviceImpl; -+ int32_t shareOption = CROSS_APP; -+ auto status = serviceImpl.GetAppShareOption("DataHub", shareOption); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+} -+ -+/** -+* @tc.name: QueryDataCommon001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, QueryDataCommon001, TestSize.Level1) -+{ -+ StoreCache::GetInstance().stores_.Clear(); -+ std::string intention = DATA_HUB_INTENTION; -+ auto store = std::make_shared(intention); -+ store->kvStore_ = std::make_shared(); -+ int foregroundUserId = 0; -+ DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); -+ intention.append(std::to_string(foregroundUserId)); -+ StoreCache::GetInstance().stores_.InsertOrAssign(intention, store); -+ UdmfServiceImpl serviceImpl; -+ QueryOption option = { -+ .intention = Intention::UD_INTENTION_DATA_HUB, -+ }; -+ std::vector dataList; -+ std::shared_ptr store1; -+ auto status = serviceImpl.QueryDataCommon(option, dataList, store1); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_ERROR); -+} -+ -+/** -+* @tc.name: PutLocal001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, PutLocal001, TestSize.Level1) -+{ -+ std::string key = "key"; -+ std::string value = "value"; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->PutLocal(key, value); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+ -+/** -+* @tc.name: GetLocal001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetLocal001, TestSize.Level1) -+{ -+ std::string key = "key"; -+ std::string value; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->GetLocal(key, value); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+ -+/** -+* @tc.name: DeleteLocal001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, DeleteLocal001, TestSize.Level1) -+{ -+ std::string key = "key"; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->DeleteLocal(key); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+ -+/** -+* @tc.name: PutRuntime001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, PutRuntime001, TestSize.Level1) -+{ -+ std::string key = "key"; -+ Runtime runtime; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->PutRuntime(key, runtime); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+ -+/** -+* @tc.name: GetRuntime001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, GetRuntime001, TestSize.Level1) -+{ -+ std::string key = "key"; -+ Runtime runtime; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->GetRuntime(key, runtime); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+ -+/** -+* @tc.name: Update001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, Update001, TestSize.Level1) -+{ -+ UnifiedData data; -+ auto rumtime = std::make_shared(); -+ UnifiedKey key(DATA_HUB_INTENTION, "com.demo.test", "111"); -+ rumtime->key = key; -+ data.runtime_ = rumtime; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->Update(data); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+ -+/** -+* @tc.name: Delete001 -+* @tc.desc: Abnormal test of OnRemoteRequest, code is invalid -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfServiceImplDbCorruptionMockTest, Delete001, TestSize.Level1) -+{ -+ std::string key = "key"; -+ auto store = std::make_shared(DATA_HUB_INTENTION); -+ store->kvStore_ = std::make_shared(); -+ auto status = store->Delete(key); -+ EXPECT_EQ(status, OHOS::UDMF::E_DB_CORRUPTED); -+} -+}; // namespace DistributedDataTest -+}; // namespace OHOS::Test -\ No newline at end of file -diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp -index 01795f4b167166759a80628c7b63c2ca4c14f8ee..f2d1b475e7fa4b3a3fe69916c10622e1b6d00683 100644 ---- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp -+++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp -@@ -737,5 +737,33 @@ HWTEST_F(UdmfRunTimeStoreTest, OnAccountChanged001, TestSize.Level1) - SetSelfTokenID(0); - observer.OnAccountChanged(eventInfo, 0); - } -+ -+/** -+* @tc.name: MarkWhenCorrupted001 -+* @tc.desc: Normal testcase of MarkWhenCorrupted -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted001, TestSize.Level1) -+{ -+ DistributedDB::DBStatus status = DistributedDB::DBStatus::OK; -+ auto store = std::make_shared(STORE_ID); -+ store->MarkWhenCorrupted(status); -+ EXPECT_FALSE(store->isCorrupted); -+} -+ -+/** -+* @tc.name: MarkWhenCorrupted001 -+* @tc.desc: Normal testcase of MarkWhenCorrupted -+* @tc.type: FUNC -+* @tc.require: -+*/ -+HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted002, TestSize.Level1) -+{ -+ DistributedDB::DBStatus status = DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; -+ auto store = std::make_shared(STORE_ID); -+ store->MarkWhenCorrupted(status); -+ EXPECT_TRUE(store->isCorrupted); -+} - }; // namespace DistributedDataTest - }; // namespace OHOS::Test -\ No newline at end of file -diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp -index 0bad354cbcba132bca066ed023a9220ac3b4061c..df04270310d8537259632563a6a0820919dad009 100644 ---- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp -+++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp -@@ -588,5 +588,39 @@ HWTEST_F(UdmfServiceImplTest, ValidateAndProcessRuntimeData004, TestSize.Level1) - int32_t result = impl.ValidateAndProcessRuntimeData(dataSet, runtime, unifiedDataSet, query, deleteKeys); - EXPECT_EQ(result, UDMF::E_OK); - } -+ -+/** -+ * @tc.name: CloseStoreWhenCorrupted001 -+ * @tc.desc: Normal test of CloseStoreWhenCorrupted -+ * @tc.type: FUNC -+ */ -+HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted001, TestSize.Level1) -+{ -+ std::string intention = "drag"; -+ StoreCache::GetInstance().CloseStores(); -+ auto store = StoreCache::GetInstance().GetStore(intention); -+ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); -+ Status status = UDMF::E_OK; -+ UdmfServiceImpl impl; -+ impl.CloseStoreWhenCorrupted(intention, status); -+ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); -+} -+ -+/** -+ * @tc.name: CloseStoreWhenCorrupted002 -+ * @tc.desc: Abnormal test of CloseStoreWhenCorrupted -+ * @tc.type: FUNC -+ */ -+HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted002, TestSize.Level1) -+{ -+ std::string intention = "drag"; -+ StoreCache::GetInstance().CloseStores(); -+ auto store = StoreCache::GetInstance().GetStore(intention); -+ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); -+ Status status = UDMF::E_DB_CORRUPTED; -+ UdmfServiceImpl impl; -+ impl.CloseStoreWhenCorrupted(intention, status); -+ EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 0); -+} - }; // namespace DistributedDataTest - }; // namespace OHOS::Test -diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp -index e218e7b1fdbf61a4159a727a935b6885adf36dd0..6b54d02a92be776b57d5dd2ba0d25b2906325461 100644 ---- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp -+++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp -@@ -60,7 +60,7 @@ Status RuntimeStore::PutLocal(const std::string &key, const std::string &value) - auto status = kvStore_->PutLocal(keyBytes, valueBytes); - if (status != DBStatus::OK) { - ZLOGE("KvStore PutLocal failed, status: %{public}d.", status); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(status); - } - return E_OK; - } -@@ -73,7 +73,7 @@ Status RuntimeStore::GetLocal(const std::string &key, std::string &value) - DBStatus status = kvStore_->GetLocal(keyBytes, valueBytes); - if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { - ZLOGE("GetLocal entry failed, key: %{public}s.", key.c_str()); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(status); - } - if (valueBytes.empty()) { - ZLOGW("GetLocal entry is empty, key: %{public}s", key.c_str()); -@@ -91,7 +91,7 @@ Status RuntimeStore::DeleteLocal(const std::string &key) - DBStatus status = kvStore_->DeleteLocal(keyBytes); - if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { - ZLOGE("DeleteLocal failed, key: %{public}s.", key.c_str()); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(status); - } - return E_OK; - } -@@ -115,9 +115,10 @@ Status RuntimeStore::Get(const std::string &key, UnifiedData &unifiedData) - { - UpdateTime(); - std::vector entries; -- if (GetEntries(UnifiedKey(key).GetKeyCommonPrefix(), entries) != E_OK) { -+ auto status = GetEntries(UnifiedKey(key).GetKeyCommonPrefix(), entries); -+ if (status != E_OK) { - ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); -- return E_DB_ERROR; -+ return status; - } - if (entries.empty()) { - ZLOGW("entries is empty, dataPrefix: %{public}s", key.c_str()); -@@ -173,9 +174,10 @@ Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) - ZLOGW("Get stored summary failed, key: %{public}s, status:%{public}d", summaryKey.c_str(), res); - UnifiedData unifiedData; - auto udKey = key.GetUnifiedKey(); -- if (Get(udKey, unifiedData) != E_OK) { -+ auto status = Get(udKey, unifiedData); -+ if (status != E_OK) { - ZLOGE("Get unified data failed, key: %{public}s", udKey.c_str()); -- return E_DB_ERROR; -+ return status; - } - UDDetails details {}; - if (PreProcessUtils::GetDetailsFromUData(unifiedData, details)) { -@@ -204,7 +206,7 @@ Status RuntimeStore::PutRuntime(const std::string &key, const Runtime &runtime) - auto res = kvStore_->Put({key.begin(), key.end()}, value); - if (res != OK) { - ZLOGE("Put failed, key:%{public}s, status:%{public}d", key.c_str(), res); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(res); - } - return E_OK; - } -@@ -220,7 +222,7 @@ Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) - } - if (res != OK || value.empty()) { - ZLOGE("Get failed, key: %{public}s, status:%{public}d", key.c_str(), res); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(res); - } - auto status = DataHandler::UnmarshalEntries(value, runtime, TAG::TAG_RUNTIME); - if (status != E_OK) { -@@ -233,14 +235,16 @@ Status RuntimeStore::GetRuntime(const std::string &key, Runtime &runtime) - Status RuntimeStore::Update(const UnifiedData &unifiedData) - { - std::string key = unifiedData.GetRuntime()->key.key; -- if (Delete(UnifiedKey(key).GetKeyCommonPrefix()) != E_OK) { -+ auto status = Delete(UnifiedKey(key).GetKeyCommonPrefix()); -+ if (status != E_OK) { - UpdateTime(); - ZLOGE("Delete unified data failed, dataPrefix: %{public}s.", key.c_str()); -- return E_DB_ERROR; -+ return status; - } -- if (Put(unifiedData) != E_OK) { -+ status = Put(unifiedData); -+ if (status != E_OK) { - ZLOGE("Update unified data failed, dataPrefix: %{public}s.", key.c_str()); -- return E_DB_ERROR; -+ return status; - } - return E_OK; - } -@@ -248,9 +252,10 @@ Status RuntimeStore::Update(const UnifiedData &unifiedData) - Status RuntimeStore::Delete(const std::string &key) - { - std::vector entries; -- if (GetEntries(key, entries) != E_OK) { -+ auto status = GetEntries(key, entries); -+ if (status != E_OK) { - ZLOGE("GetEntries failed, dataPrefix: %{public}s.", key.c_str()); -- return E_DB_ERROR; -+ return status; - } - if (entries.empty()) { - ZLOGD("entries is empty."); -@@ -382,7 +387,7 @@ Status RuntimeStore::GetBatchData(const std::string &dataPrefix, std::vector(status)); -+ if (delegateManager_->DeleteKvStore(storeId_) != DBStatus::OK) { -+ ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(status)); -+ } -+ return false; -+ } - if (status != DBStatus::OK) { - ZLOGE("GetKvStore fail, status: %{public}d.", static_cast(status)); - return false; -@@ -442,6 +454,13 @@ bool RuntimeStore::Init() - if (retStatus != DBStatus::OK) { - ZLOGE("CloseKvStore fail, status: %{public}d.", static_cast(retStatus)); - } -+ if (isCorrupted) { -+ ZLOGI("start to delete runtime kvStore."); -+ retStatus = delegateManager_->DeleteKvStore(storeId_); -+ if (retStatus != DBStatus::OK) { -+ ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(retStatus)); -+ } -+ } - }; - kvStore_ = std::shared_ptr(delegate, release); - uint32_t pragmData = 16 * 1024 * 1024; -@@ -549,7 +568,7 @@ Status RuntimeStore::GetEntries(const std::string &dataPrefix, std::vectorGetEntries(dbQuery, entries); - if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { - ZLOGE("KvStore getEntries failed, status: %{public}d.", static_cast(status)); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(status); - } - return E_OK; - } -@@ -559,7 +578,7 @@ Status RuntimeStore::PutEntries(const std::vector &entries) - DBStatus status = kvStore_->PutBatch(entries); - if (status != DBStatus::OK) { - ZLOGE("putBatch failed, status: %{public}d.", status); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(status); - } - return E_OK; - } -@@ -569,10 +588,19 @@ Status RuntimeStore::DeleteEntries(const std::vector &keys) - DBStatus status = kvStore_->DeleteBatch(keys); - if (status != DBStatus::OK) { - ZLOGE("deleteBatch failed, status: %{public}d.", status); -- return E_DB_ERROR; -+ return MarkWhenCorrupted(status); - } - return E_OK; - } - -+Status RuntimeStore::MarkWhenCorrupted(DistributedDB::DBStatus status) -+{ -+ if (status == INVALID_PASSWD_OR_CORRUPTED_DB) { -+ ZLOGE("Kv database corrupted"); -+ isCorrupted = true; -+ return E_DB_CORRUPTED; -+ } -+ return E_DB_ERROR; -+} - } // namespace UDMF - } // namespace OHOS -\ No newline at end of file -diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h -index d5f4be1a84c048369bd9e3bb5f52fde1cf951f23..421151f80e113ba2819d31aa60c28c8405096b3f 100644 ---- a/services/distributeddataservice/service/udmf/store/runtime_store.h -+++ b/services/distributeddataservice/service/udmf/store/runtime_store.h -@@ -64,6 +64,9 @@ private: - void NotifySyncProcss(const DevSyncProcessMap &processMap, ProcessCallback callback, - const DevNameMap &deviceNameMap); - Status PutSummary(const UnifiedData &data, std::vector &entries); -+ Status MarkWhenCorrupted(DistributedDB::DBStatus status); -+ bool isCorrupted = false; -+ - }; - } // namespace UDMF - } // namespace OHOS -diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp -index 545b549a17b0145ca1a1957ba92ce5c7986594c9..30ae5c7a160c9c86cb5b23ea7f703e557b6f1f88 100644 ---- a/services/distributeddataservice/service/udmf/store/store_cache.cpp -+++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp -@@ -38,7 +38,6 @@ std::shared_ptr StoreCache::GetStore(std::string intention) - } - std::string key = intention; - key.append(std::to_string(foregroundUserId)); -- - stores_.Compute(key, [&store, intention](const auto &key, std::shared_ptr &storePtr) -> bool { - if (storePtr != nullptr) { - store = storePtr; -@@ -56,7 +55,6 @@ std::shared_ptr StoreCache::GetStore(std::string intention) - } - return false; - }); -- - std::unique_lock lock(taskMutex_); - if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) { - taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this)); -@@ -94,6 +92,19 @@ void StoreCache::CloseStores() - stores_.Clear(); - } - -+void StoreCache::RemoveStore(std::string intention) -+{ -+ ZLOGI("RemoveStore, intention:%{public}s", intention.c_str()); -+ int foregroundUserId = 0; -+ if (!DistributedData::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId)) { -+ ZLOGE("QueryForegroundUserId failed."); -+ return; -+ } -+ std::string key = intention; -+ key.append(std::to_string(foregroundUserId)); -+ stores_.Erase(key); -+} -+ - bool StoreCache::IsValidIntention(const std::string &intention) - { - return UnifiedDataUtils::GetIntentionByString(intention) != UD_INTENTION_BUTT; -diff --git a/services/distributeddataservice/service/udmf/store/store_cache.h b/services/distributeddataservice/service/udmf/store/store_cache.h -index 5d3918d2d0bd44121b6e8f7618eade4103ff3358..b71481dbea8990f8b63682bbd48eb6a3eec79d38 100644 ---- a/services/distributeddataservice/service/udmf/store/store_cache.h -+++ b/services/distributeddataservice/service/udmf/store/store_cache.h -@@ -28,6 +28,7 @@ public: - static StoreCache &GetInstance(); - void SetThreadPool(std::shared_ptr executors); - void CloseStores(); -+ void RemoveStore(std::string intention); - - private: - StoreCache() {} -diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp -index bade1ef4fd9bb6b01e5f1990ee3682eae09181a3..9c8bc2e4a11a6265790fa8a34417aedb89d89eef 100644 ---- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp -+++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp -@@ -128,18 +128,15 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData - ZLOGE("UnifiedData is invalid."); - return E_INVALID_PARAMETERS; - } -- - if (!UnifiedDataUtils::IsValidIntention(option.intention)) { - ZLOGE("Invalid parameters intention: %{public}d.", option.intention); - return E_INVALID_PARAMETERS; - } -- - // imput runtime info before put it into store and save one privilege - if (PreProcessUtils::FillRuntimeInfo(unifiedData, option) != E_OK) { - ZLOGE("Imputation failed"); - return E_ERROR; - } -- - std::string intention = unifiedData.GetRuntime()->key.intention; - if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) { - int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData); -@@ -155,9 +152,10 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData - ZLOGE("Get store failed:%{public}s", intention.c_str()); - return E_DB_ERROR; - } -- -- if (store->Put(unifiedData) != E_OK) { -- ZLOGE("Put unified data failed:%{public}s", intention.c_str()); -+ auto status = store->Put(unifiedData); -+ if (status != E_OK) { -+ ZLOGE("Put unified data failed:%{public}s, status:%{public}d", intention.c_str(), status); -+ CloseStoreWhenCorrupted(intention, status); - return E_DB_ERROR; - } - key = unifiedData.GetRuntime()->key.GetUnifiedKey(); -@@ -223,7 +221,8 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni - int32_t res = store->Get(query.key, unifiedData); - if (res != E_OK) { - ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str()); -- return res; -+ CloseStoreWhenCorrupted(key.intention, static_cast(res)); -+ return E_DB_ERROR; - } - - if (!unifiedData.IsComplete()) { -@@ -420,6 +419,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi - int32_t res = store->Get(query.key, data); - if (res != E_OK) { - ZLOGE("Get data failed:%{public}s", key.intention.c_str()); -+ CloseStoreWhenCorrupted(key.intention, static_cast(res)); - return res; - } - if (data.IsEmpty()) { -@@ -440,8 +440,10 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi - runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); - unifiedData.SetRuntime(*runtime); - PreProcessUtils::SetRecordUid(unifiedData); -- if (store->Update(unifiedData) != E_OK) { -+ res = store->Update(unifiedData); -+ if (res != E_OK) { - ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); -+ CloseStoreWhenCorrupted(key.intention, static_cast(res)); - return E_DB_ERROR; - } - return E_OK; -@@ -480,7 +482,8 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector(status)); -+ return E_DB_ERROR; - } - if (dataSet.empty()) { - ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); -@@ -498,8 +501,10 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorDeleteBatch(deleteKeys) != E_OK) { -+ status = store->DeleteBatch(deleteKeys); -+ if (status != E_OK) { - ZLOGE("Remove data failed."); -+ CloseStoreWhenCorrupted(key.intention, static_cast(status)); - return E_DB_ERROR; - } - return E_OK; -@@ -551,9 +556,10 @@ int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) - ZLOGE("Get store failed:%{public}s", key.intention.c_str()); - return E_DB_ERROR; - } -- -- if (store->GetSummary(key, summary) != E_OK) { -+ auto status = store->GetSummary(key, summary); -+ if (status != E_OK) { - ZLOGE("Store get summary failed:%{public}s", key.intention.c_str()); -+ CloseStoreWhenCorrupted(key.intention, status); - return E_DB_ERROR; - } - return E_OK; -@@ -598,14 +604,17 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi - } - if (res != E_OK) { - ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); -+ CloseStoreWhenCorrupted(key.intention, res); - return res; - } - runtime.privileges.emplace_back(privilege); - res = store->PutRuntime(query.key, runtime); - if (res != E_OK) { - ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); -+ CloseStoreWhenCorrupted(key.intention, res); -+ return E_DB_ERROR; - } -- return res; -+ return E_OK; - } - - int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) -@@ -715,6 +724,7 @@ int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result) - auto res = store->GetRuntime(query.key, runtime); - if (res != E_OK) { - ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); -+ CloseStoreWhenCorrupted(key.intention, res); - return E_DB_ERROR; - } - -@@ -751,9 +761,10 @@ int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t - ZLOGE("SetAppShareOption failed,shareOption already set:%{public}s", shareOptionTmp.c_str()); - return E_SETTINGS_EXISTED; - } -- -- if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) { -- ZLOGE("Store get unifiedData failed:%{public}d", shareOption); -+ auto status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)); -+ if (status != E_OK) { -+ ZLOGE("Store get unifiedData failed:%{public}d", status); -+ CloseStoreWhenCorrupted(intention, status); - return E_DB_ERROR; - } - return E_OK; -@@ -775,7 +786,8 @@ int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t - int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); - if (ret != E_OK) { - ZLOGW("GetLocal failed:%{public}s", intention.c_str()); -- return ret; -+ CloseStoreWhenCorrupted(intention, static_cast(ret)); -+ return E_DB_ERROR; - } - ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str()); - shareOption = ShareOptionsUtil::GetEnumNum(appShareOption); -@@ -802,8 +814,10 @@ int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) - } - - UnifiedData unifiedData; -- if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) { -- ZLOGE("Store DeleteLocal failed:%{public}s", intention.c_str()); -+ auto status = store->DeleteLocal(std::to_string(accessTokenIDEx)); -+ if (status != E_OK) { -+ ZLOGE("Store DeleteLocal failed:%{public}s, status:%{public}d", intention.c_str(), status); -+ CloseStoreWhenCorrupted(intention, status); - return E_DB_ERROR; - } - return E_OK; -@@ -849,8 +863,10 @@ int32_t UdmfServiceImpl::QueryDataCommon( - ZLOGE("Get store failed:%{public}s", intention.c_str()); - return E_DB_ERROR; - } -- if (store->GetBatchData(dataPrefix, dataSet) != E_OK) { -- ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str()); -+ auto status = store->GetBatchData(dataPrefix, dataSet); -+ if (status != E_OK) { -+ ZLOGE("Get dataSet failed, dataPrefix: %{public}s, status:%{public}d.", dataPrefix.c_str(), status); -+ CloseStoreWhenCorrupted(intention, status); - return E_DB_ERROR; - } - return E_OK; -@@ -1135,8 +1151,10 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptrPutSummary(udkey, summary) != E_OK) { -- ZLOGE("Put summary failed:%{public}s", key.c_str()); -+ auto status = store->PutSummary(udkey, summary); -+ if (status != E_OK) { -+ ZLOGE("Put summary failed:%{public}s, status:%{public}d", key.c_str(), status); -+ CloseStoreWhenCorrupted(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status); - return E_DB_ERROR; - } - return E_OK; -@@ -1239,5 +1257,13 @@ bool UdmfServiceImpl::IsValidInput(const QueryOption &query, UnifiedData &unifie - } - return true; - } -+ -+void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, Status status) -+{ -+ if (status == E_DB_CORRUPTED) { -+ ZLOGE("Kv database corrupted, start to remove store"); -+ StoreCache::GetInstance().RemoveStore(intention); -+ } -+} - } // namespace UDMF - } // namespace OHOS -\ No newline at end of file -diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h -index b728d8199086fc592b8692696904d4f00be01c4c..f8aed0684b73fa97ebd57c9f531536792d569771 100644 ---- a/services/distributeddataservice/service/udmf/udmf_service_impl.h -+++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h -@@ -83,6 +83,7 @@ private: - int32_t ValidateAndProcessRuntimeData(const std::vector &dataSet, std::shared_ptr runtime, - std::vector &unifiedDataSet, const QueryOption &query, std::vector &deleteKeys); - int32_t CheckAppId(std::shared_ptr runtime, const std::string &bundleName); -+ void CloseStoreWhenCorrupted(const std::string &intention, Status status); - class Factory { - public: - Factory(); diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index a4956c069..8202dc149 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -2114,10 +2114,7 @@ ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { blocklist = "${datamgr_service_path}/cfi_blocklist.txt" } sources = [ - "udmf_db_corruption_mock_test.cpp", - "mock/kv_store_nb_delegate_corruption_mock.cpp", - "mock/preprocess_utils_mock.cpp", - "${data_service_path}/service/udmf/udmf_service_impl.cpp", + "${data_service_path}/app/src/kvstore_meta_manager.cpp", "${data_service_path}/service/udmf/lifecycle/clean_on_startup.cpp", "${data_service_path}/service/udmf/lifecycle/clean_on_timeout.cpp", "${data_service_path}/service/udmf/lifecycle/lifecycle_manager.cpp", @@ -2130,8 +2127,11 @@ ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { "${data_service_path}/service/udmf/store/runtime_store.cpp", "${data_service_path}/service/udmf/store/store_account_observer.cpp", "${data_service_path}/service/udmf/store/store_cache.cpp", + "${data_service_path}/service/udmf/udmf_service_impl.cpp", "${data_service_path}/service/udmf/udmf_service_stub.cpp", - "${data_service_path}/app/src/kvstore_meta_manager.cpp", + "mock/kv_store_nb_delegate_corruption_mock.cpp", + "mock/preprocess_utils_mock.cpp", + "udmf_db_corruption_mock_test.cpp", ] include_dirs = [ @@ -2151,8 +2151,8 @@ ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { external_deps = [ "ability_base:base", - "ability_base:zuri", "ability_base:want", + "ability_base:zuri", "ability_runtime:uri_permission_mgr", "access_token:libaccesstoken_sdk", "access_token:libnativetoken_shared", @@ -2161,25 +2161,25 @@ ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { "app_file_service:remote_file_share_native", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", + "dataclassification:data_transit_mgr", "device_manager:devicemanagersdk", "dfs_service:distributed_file_daemon_kit_inner", + "dsoftbus:softbus_client", + "googletest:gmock_main", + "googletest:gtest_main", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "ipc:ipc_core", "kv_store:distributeddata_inner", - "kv_store:distributeddb", "kv_store:distributeddata_mgr", + "kv_store:distributeddb", + "openssl:libcrypto_shared", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", "udmf:udmf_client", "udmf:utd_client", - "dsoftbus:softbus_client", - "samgr:samgr_proxy", - "safwk:system_ability_fwk", - "openssl:libcrypto_shared", - "googletest:gmock_main", - "googletest:gtest_main", - "dataclassification:data_transit_mgr", ] deps = [ -- Gitee From 5ca623a68d9fe4a8f582bd9e99d3457ea34fb7cd Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 18:16:29 +0800 Subject: [PATCH 03/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I875a451773ddf7664eaf6db5f00b3aa0aa9660de --- .../kv_store_nb_delegate_corruption_mock.cpp | 291 ------------------ .../test/mock/preprocess_utils_mock.cpp | 2 - .../service/udmf/store/runtime_store.h | 1 - 3 files changed, 294 deletions(-) diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp index 04a12f2a0..98dc2b0f2 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp @@ -22,36 +22,11 @@ DBStatus KvStoreNbDelegateCorruptionMock::Get(const Key &key, Value &value) cons return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } -DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, std::vector &entries) const -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const -{ - return DBStatus::OK; -} - DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, std::vector &entries) const { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } -DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, KvStoreResultSet *&resultSet) const -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::GetCount(const Query &query, int &count) const -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::CloseResultSet(KvStoreResultSet *&resultSet) -{ - return DBStatus::OK; -} - DBStatus KvStoreNbDelegateCorruptionMock::Put(const Key &key, const Value &value) { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; @@ -62,26 +37,11 @@ DBStatus KvStoreNbDelegateCorruptionMock::PutBatch(const std::vector &ent return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } -DBStatus KvStoreNbDelegateCorruptionMock::DeleteBatch(const std::vector &keys) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Delete(const Key &key) -{ - return DBStatus::OK; -} - DBStatus KvStoreNbDelegateCorruptionMock::GetLocal(const Key &key, Value &value) const { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } -DBStatus KvStoreNbDelegateCorruptionMock::GetLocalEntries(const Key &keyPrefix, std::vector &entries) const -{ - return DBStatus::OK; -} - DBStatus KvStoreNbDelegateCorruptionMock::PutLocal(const Key &key, const Value &value) { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; @@ -91,255 +51,4 @@ DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocal(const Key &key) { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } - -DBStatus KvStoreNbDelegateCorruptionMock::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, - const KvStoreNbPublishOnConflict &onConflict) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::RegisterObserver(const Key &key, unsigned int mode, - KvStoreObserver *observer) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::UnRegisterObserver(const KvStoreObserver *observer) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device) -{ - return DBStatus::OK; -} - -std::string KvStoreNbDelegateCorruptionMock::GetStoreId() const -{ - return "ok"; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, - const std::function &devicesMap)> &onComplete, - bool wait) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Pragma(PragmaCmd cmd, PragmaData ¶mData) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetConflictNotifier(int conflictType, - const KvStoreNbConflictNotifier ¬ifier) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Rekey(const CipherPassword &password) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Export(const std::string &filePath, - const CipherPassword &passwd, bool force) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Import(const std::string &filePath, const CipherPassword &passwd, - bool isNeedIntegrityCheck) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::StartTransaction() -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Commit() -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Rollback() -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::PutLocalBatch(const std::vector &entries) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocalBatch(const std::vector &keys) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::GetSecurityOption(SecurityOption &option) const -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, - const std::function &devicesMap)> &onComplete, - const Query &query, bool wait) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::CheckIntegrity() const -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetEqualIdentifier(const std::string &identifier, - const std::vector &targets) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetPushDataInterceptor(const PushDataInterceptor &interceptor) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SubscribeRemoteQuery(const std::vector &devices, - const std::function &devicesMap)> &onComplete, - const Query &query, bool wait) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::UnSubscribeRemoteQuery(const std::vector &devices, - const std::function &devicesMap)> &onComplete, - const Query &query, bool wait) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData() -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::GetKeys(const Key &keyPrefix, std::vector &keys) const -{ - return DBStatus::OK; -} - -size_t KvStoreNbDelegateCorruptionMock::GetSyncDataSize(const std::string &device) const -{ - size_t size = 0; - return size; -} - -DBStatus KvStoreNbDelegateCorruptionMock::UpdateKey(const UpdateKeyCallback &callback) -{ - return DBStatus::OK; -} - -std::pair KvStoreNbDelegateCorruptionMock::GetWatermarkInfo(const std::string &device) -{ - std::pair ret; - return ret; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDB(const std::map> &cloudDBs) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDbSchema(const std::map &schema) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, ClearMode mode) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) -{ - return DBStatus::OK; -} - -int32_t KvStoreNbDelegateCorruptionMock::GetTaskCount() -{ - int32_t taskCount = taskCountMock_; - return taskCount; -} - -void KvStoreNbDelegateCorruptionMock::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) -{ - auto callback_ = callback; -} - -std::pair> KvStoreNbDelegateCorruptionMock::GetCloudVersion( - const std::string &device) -{ - if (device.empty()) { - return { DBStatus::OK, {} }; - } else if (device == "test") { - return { DBStatus::DB_ERROR, {} }; - } else if (device == "device") { - return { DBStatus::DB_ERROR, {{device, device}} }; - } else { - return { DBStatus::OK, {{device, device}} }; - } -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::SetCloudSyncConfig(const CloudSyncConfig &config) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::GetDeviceEntries(const std::string &device, std::vector &entries) const -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) -{ - return DBStatus::OK; -} - -DBStatus KvStoreNbDelegateCorruptionMock::CancelSync(uint32_t syncId) -{ - return DBStatus::OK; -} - -KvStoreNbDelegate::DatabaseStatus KvStoreNbDelegateCorruptionMock::GetDatabaseStatus() const -{ - return {}; -} - -DBStatus KvStoreNbDelegateCorruptionMock::ClearMetaData(ClearKvMetaDataOption option) -{ - return DBStatus::OK; -} } // namespace DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp index af03ce4d6..e65ccc5d0 100644 --- a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp +++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp @@ -79,7 +79,6 @@ time_t PreProcessUtils::GetTimestamp() int32_t PreProcessUtils::GetHapUidByToken(uint32_t tokenId, int &userId) { - userId = 100; return E_OK; } @@ -87,7 +86,6 @@ bool PreProcessUtils::GetHapBundleNameByToken(int tokenId, std::string &bundleNa { bundleName = "processName"; return true; - } bool PreProcessUtils::GetNativeProcessNameByToken(int tokenId, std::string &processName) diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h index 421151f80..c4457103e 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -66,7 +66,6 @@ private: Status PutSummary(const UnifiedData &data, std::vector &entries); Status MarkWhenCorrupted(DistributedDB::DBStatus status); bool isCorrupted = false; - }; } // namespace UDMF } // namespace OHOS -- Gitee From 350f7ad8347767346c8b391b7261139fcb461246 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 20:42:04 +0800 Subject: [PATCH 04/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I54bc133845c162b7d7e6ceff97983daa0c70629f --- .../kv_store_nb_delegate_corruption_mock.cpp | 291 ++++++++++++++++++ .../service/test/udmf_run_time_store_test.cpp | 10 +- .../service/udmf/store/runtime_store.cpp | 1 + 3 files changed, 293 insertions(+), 9 deletions(-) diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp index 98dc2b0f2..04a12f2a0 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp @@ -22,11 +22,36 @@ DBStatus KvStoreNbDelegateCorruptionMock::Get(const Key &key, Value &value) cons return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const +{ + return DBStatus::OK; +} + DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, std::vector &entries) const { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } +DBStatus KvStoreNbDelegateCorruptionMock::GetEntries(const Query &query, KvStoreResultSet *&resultSet) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetCount(const Query &query, int &count) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::CloseResultSet(KvStoreResultSet *&resultSet) +{ + return DBStatus::OK; +} + DBStatus KvStoreNbDelegateCorruptionMock::Put(const Key &key, const Value &value) { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; @@ -37,11 +62,26 @@ DBStatus KvStoreNbDelegateCorruptionMock::PutBatch(const std::vector &ent return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } +DBStatus KvStoreNbDelegateCorruptionMock::DeleteBatch(const std::vector &keys) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Delete(const Key &key) +{ + return DBStatus::OK; +} + DBStatus KvStoreNbDelegateCorruptionMock::GetLocal(const Key &key, Value &value) const { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } +DBStatus KvStoreNbDelegateCorruptionMock::GetLocalEntries(const Key &keyPrefix, std::vector &entries) const +{ + return DBStatus::OK; +} + DBStatus KvStoreNbDelegateCorruptionMock::PutLocal(const Key &key, const Value &value) { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; @@ -51,4 +91,255 @@ DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocal(const Key &key) { return DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; } + +DBStatus KvStoreNbDelegateCorruptionMock::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp, + const KvStoreNbPublishOnConflict &onConflict) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RegisterObserver(const Key &key, unsigned int mode, + KvStoreObserver *observer) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UnRegisterObserver(const KvStoreObserver *observer) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device) +{ + return DBStatus::OK; +} + +std::string KvStoreNbDelegateCorruptionMock::GetStoreId() const +{ + return "ok"; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Pragma(PragmaCmd cmd, PragmaData ¶mData) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetConflictNotifier(int conflictType, + const KvStoreNbConflictNotifier ¬ifier) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Rekey(const CipherPassword &password) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Export(const std::string &filePath, + const CipherPassword &passwd, bool force) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Import(const std::string &filePath, const CipherPassword &passwd, + bool isNeedIntegrityCheck) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::StartTransaction() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Commit() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Rollback() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::PutLocalBatch(const std::vector &entries) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::DeleteLocalBatch(const std::vector &keys) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetSecurityOption(SecurityOption &option) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetRemotePushFinishedNotify(const RemotePushFinishedNotifier ¬ifier) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const std::vector &devices, SyncMode mode, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::CheckIntegrity() const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetEqualIdentifier(const std::string &identifier, + const std::vector &targets) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetPushDataInterceptor(const PushDataInterceptor &interceptor) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UnSubscribeRemoteQuery(const std::vector &devices, + const std::function &devicesMap)> &onComplete, + const Query &query, bool wait) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData() +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetKeys(const Key &keyPrefix, std::vector &keys) const +{ + return DBStatus::OK; +} + +size_t KvStoreNbDelegateCorruptionMock::GetSyncDataSize(const std::string &device) const +{ + size_t size = 0; + return size; +} + +DBStatus KvStoreNbDelegateCorruptionMock::UpdateKey(const UpdateKeyCallback &callback) +{ + return DBStatus::OK; +} + +std::pair KvStoreNbDelegateCorruptionMock::GetWatermarkInfo(const std::string &device) +{ + std::pair ret; + return ret; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDB(const std::map> &cloudDBs) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetCloudDbSchema(const std::map &schema) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, ClearMode mode) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) +{ + return DBStatus::OK; +} + +int32_t KvStoreNbDelegateCorruptionMock::GetTaskCount() +{ + int32_t taskCount = taskCountMock_; + return taskCount; +} + +void KvStoreNbDelegateCorruptionMock::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) +{ + auto callback_ = callback; +} + +std::pair> KvStoreNbDelegateCorruptionMock::GetCloudVersion( + const std::string &device) +{ + if (device.empty()) { + return { DBStatus::OK, {} }; + } else if (device == "test") { + return { DBStatus::DB_ERROR, {} }; + } else if (device == "device") { + return { DBStatus::DB_ERROR, {{device, device}} }; + } else { + return { DBStatus::OK, {{device, device}} }; + } +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::GetDeviceEntries(const std::string &device, std::vector &entries) const +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) +{ + return DBStatus::OK; +} + +DBStatus KvStoreNbDelegateCorruptionMock::CancelSync(uint32_t syncId) +{ + return DBStatus::OK; +} + +KvStoreNbDelegate::DatabaseStatus KvStoreNbDelegateCorruptionMock::GetDatabaseStatus() const +{ + return {}; +} + +DBStatus KvStoreNbDelegateCorruptionMock::ClearMetaData(ClearKvMetaDataOption option) +{ + return DBStatus::OK; +} } // namespace DistributedDB \ No newline at end of file diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp index f2d1b475e..53dd9d421 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -642,18 +642,10 @@ HWTEST_F(UdmfRunTimeStoreTest, GetSummary, TestSize.Level1) auto store = std::make_shared(STORE_ID); bool result = store->Init(); EXPECT_TRUE(result); - - UnifiedData data; - UDDetails details; - details.insert({ "udmf_key", "udmf_value" }); - auto text = std::make_shared(); - text->SetDetails(details); - data.AddRecord(text); - Summary summary; UnifiedKey key(KEY_PREFIX); auto status = store->GetSummary(key, summary); - ASSERT_EQ(status, E_DB_ERROR); + ASSERT_EQ(status, E_NOT_FOUND); } /** diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 6b54d02a9..06255c256 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -181,6 +181,7 @@ Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) } UDDetails details {}; if (PreProcessUtils::GetDetailsFromUData(unifiedData, details)) { + ZLOGE("GetDetailsFromUData11111"); return PreProcessUtils::GetSummaryFromDetails(details, summary); } UnifiedDataHelper::GetSummary(unifiedData, summary); -- Gitee From 81ae928e0816782efbbc4e56e861585c623ff499 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 20:43:33 +0800 Subject: [PATCH 05/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I869c17cc5af2997aa1dc47fde2ecf697f459bb84 --- .../distributeddataservice/service/udmf/store/runtime_store.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 06255c256..6b54d02a9 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -181,7 +181,6 @@ Status RuntimeStore::GetSummary(UnifiedKey &key, Summary &summary) } UDDetails details {}; if (PreProcessUtils::GetDetailsFromUData(unifiedData, details)) { - ZLOGE("GetDetailsFromUData11111"); return PreProcessUtils::GetSummaryFromDetails(details, summary); } UnifiedDataHelper::GetSummary(unifiedData, summary); -- Gitee From e8abc51e101cc135985fc38691c5fe85b66e90ec Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 21:13:28 +0800 Subject: [PATCH 06/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I8cfb1d09a8125427d4ae2e1d8ca88521e0c0aa89 --- .../service/udmf/store/runtime_store.cpp | 20 ++++++------------- .../service/udmf/udmf_service_impl.cpp | 4 +--- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 6b54d02a9..45e46563b 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -433,18 +433,14 @@ bool RuntimeStore::Init() delegate = nbDelegate; status = dbStatus; }); - if (status == INVALID_PASSWD_OR_CORRUPTED_DB) { - ZLOGE("GetKvStore fail, database corrupted, status: %{public}d.", static_cast(status)); - if (delegateManager_->DeleteKvStore(storeId_) != DBStatus::OK) { - ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(status)); - } - return false; - } if (status != DBStatus::OK) { ZLOGE("GetKvStore fail, status: %{public}d.", static_cast(status)); + if (status == INVALID_PASSWD_OR_CORRUPTED_DB && + (status = delegateManager_->DeleteKvStore(storeId_)) != DBStatus::OK) { + ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(status)); + } return false; } - auto release = [this](KvStoreNbDelegate *delegate) { ZLOGI("Release runtime kvStore."); if (delegate == nullptr) { @@ -454,12 +450,8 @@ bool RuntimeStore::Init() if (retStatus != DBStatus::OK) { ZLOGE("CloseKvStore fail, status: %{public}d.", static_cast(retStatus)); } - if (isCorrupted) { - ZLOGI("start to delete runtime kvStore."); - retStatus = delegateManager_->DeleteKvStore(storeId_); - if (retStatus != DBStatus::OK) { - ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(retStatus)); - } + if (isCorrupted && (retStatus = delegateManager_->DeleteKvStore(storeId_)) != DBStatus::OK) { + ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(retStatus)); } }; kvStore_ = std::shared_ptr(delegate, release); diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 9c8bc2e4a..4b3e158fd 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -431,7 +431,6 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi ZLOGE("Invalid parameter, runtime is nullptr."); return E_DB_ERROR; } - if (runtime->tokenId != query.tokenId && !HasDatahubPriviledge(bundleName) && CheckAppId(runtime, bundleName) != E_OK) { ZLOGE("Update failed: tokenId or appId mismatch, bundleName: %{public}s", bundleName.c_str()); @@ -440,8 +439,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi runtime->lastModifiedTime = PreProcessUtils::GetTimestamp(); unifiedData.SetRuntime(*runtime); PreProcessUtils::SetRecordUid(unifiedData); - res = store->Update(unifiedData); - if (res != E_OK) { + if ((res = store->Update(unifiedData)) != E_OK) { ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); CloseStoreWhenCorrupted(key.intention, static_cast(res)); return E_DB_ERROR; -- Gitee From 45bac89cbde8bb0ae4277dc9c6c18bb82d615638 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 21:27:11 +0800 Subject: [PATCH 07/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I0cc825fd3344e5d073e987b239b6c376d9cdead9 --- .../test/mock/kv_store_nb_delegate_corruption_mock.cpp | 6 ++++-- .../service/udmf/udmf_service_impl.cpp | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp index 04a12f2a0..006a01df2 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp @@ -278,7 +278,8 @@ DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &de return DBStatus::OK; } -DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) +DBStatus KvStoreNbDelegateCorruptionMock::RemoveDeviceData(const std::string &device, + const std::string &user, ClearMode mode) { return DBStatus::OK; } @@ -323,7 +324,8 @@ DBStatus KvStoreNbDelegateCorruptionMock::GetDeviceEntries(const std::string &de return DBStatus::OK; } -DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, const DeviceSyncProcessCallback &onProcess) +DBStatus KvStoreNbDelegateCorruptionMock::Sync(const DeviceSyncOption &option, + const DeviceSyncProcessCallback &onProcess) { return DBStatus::OK; } diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 4b3e158fd..5a48cd4d7 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -398,7 +398,6 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi { UnifiedKey key(query.key); if (!IsValidInput(query, unifiedData, key)) { - ZLOGE("Invalid input, key = %{public}s", query.key.c_str()); return E_INVALID_PARAMETERS; } std::string bundleName; -- Gitee From 7d5effbd8a77bf6d75c0797663176b4a4714d7f8 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 21:30:44 +0800 Subject: [PATCH 08/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I1a1d6cb7259a6dcb41d0b79e15abd6e6d5d26b52 --- services/distributeddataservice/service/test/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 8202dc149..ffa0204d8 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -2161,6 +2161,7 @@ ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { "app_file_service:remote_file_share_native", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", + "c_utils:utils", "dataclassification:data_transit_mgr", "device_manager:devicemanagersdk", "dfs_service:distributed_file_daemon_kit_inner", -- Gitee From fc75de09106eb85eb857306dce9d379961015c00 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 21:45:35 +0800 Subject: [PATCH 09/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I03abadf3cd8e4791f6b936ed8739bf83f7d8aa3b --- services/distributeddataservice/service/test/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index ffa0204d8..87642201a 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -2180,7 +2180,6 @@ ohos_unittest("UdmfServiceImplDbCorruptionMockTest") { "safwk:system_ability_fwk", "samgr:samgr_proxy", "udmf:udmf_client", - "udmf:utd_client", ] deps = [ -- Gitee From a2c13be18108ee7fbddd9723a6099d571d33764b Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 22:09:56 +0800 Subject: [PATCH 10/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I3c476724cd890f4399226fdbbe6fe1b44c3084aa --- .../service/udmf/store/runtime_store.cpp | 2 +- .../distributeddataservice/service/udmf/udmf_service_impl.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 45e46563b..1bbb11851 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -577,7 +577,7 @@ Status RuntimeStore::PutEntries(const std::vector &entries) Status RuntimeStore::DeleteEntries(const std::vector &keys) { - DBStatus status = kvStore_->DeleteBatch(keys); + DBStatus status = INVALID_PASSWD_OR_CORRUPTED_DB; if (status != DBStatus::OK) { ZLOGE("deleteBatch failed, status: %{public}d.", status); return MarkWhenCorrupted(status); diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 5a48cd4d7..1f179e089 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -479,7 +479,6 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector(status)); return E_DB_ERROR; } if (dataSet.empty()) { @@ -609,9 +608,8 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi if (res != E_OK) { ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); CloseStoreWhenCorrupted(key.intention, res); - return E_DB_ERROR; } - return E_OK; + return res; } int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) -- Gitee From fa84e2c79efff2b57a4d841a500ae87583e98347 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 22:12:58 +0800 Subject: [PATCH 11/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I8078b8b145ca94a035a167c522e54c30505dc305 --- .../distributeddataservice/service/udmf/store/runtime_store.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 1bbb11851..45e46563b 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -577,7 +577,7 @@ Status RuntimeStore::PutEntries(const std::vector &entries) Status RuntimeStore::DeleteEntries(const std::vector &keys) { - DBStatus status = INVALID_PASSWD_OR_CORRUPTED_DB; + DBStatus status = kvStore_->DeleteBatch(keys); if (status != DBStatus::OK) { ZLOGE("deleteBatch failed, status: %{public}d.", status); return MarkWhenCorrupted(status); -- Gitee From 3813391e13441f69ec1c397f445aa090a2d7b4ba Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Sat, 5 Jul 2025 09:56:08 +0800 Subject: [PATCH 12/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: Ie6c21564539dd8414d8d431667163c59e934f62a --- .../service/udmf/udmf_service_impl.cpp | 40 +++++++++---------- .../service/udmf/udmf_service_impl.h | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 1f179e089..66f83afa0 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -146,13 +146,12 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData } } PreProcessUtils::SetRecordUid(unifiedData); - auto store = StoreCache::GetInstance().GetStore(intention); if (store == nullptr) { ZLOGE("Get store failed:%{public}s", intention.c_str()); return E_DB_ERROR; } - auto status = store->Put(unifiedData); + int32_t status = store->Put(unifiedData); if (status != E_OK) { ZLOGE("Put unified data failed:%{public}s, status:%{public}d", intention.c_str(), status); CloseStoreWhenCorrupted(intention, status); @@ -221,8 +220,8 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni int32_t res = store->Get(query.key, unifiedData); if (res != E_OK) { ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str()); - CloseStoreWhenCorrupted(key.intention, static_cast(res)); - return E_DB_ERROR; + CloseStoreWhenCorrupted(key.intention, res); + return res; } if (!unifiedData.IsComplete()) { @@ -418,7 +417,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi int32_t res = store->Get(query.key, data); if (res != E_OK) { ZLOGE("Get data failed:%{public}s", key.intention.c_str()); - CloseStoreWhenCorrupted(key.intention, static_cast(res)); + CloseStoreWhenCorrupted(key.intention, res); return res; } if (data.IsEmpty()) { @@ -440,8 +439,8 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi PreProcessUtils::SetRecordUid(unifiedData); if ((res = store->Update(unifiedData)) != E_OK) { ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); - CloseStoreWhenCorrupted(key.intention, static_cast(res)); - return E_DB_ERROR; + CloseStoreWhenCorrupted(key.intention, res); + return res; } return E_OK; } @@ -476,10 +475,10 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector dataSet; std::shared_ptr store; - auto status = QueryDataCommon(query, dataSet, store); + int32_t status = QueryDataCommon(query, dataSet, store); if (status != E_OK) { ZLOGE("QueryDataCommon failed."); - return E_DB_ERROR; + return status; } if (dataSet.empty()) { ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention); @@ -500,7 +499,7 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorDeleteBatch(deleteKeys); if (status != E_OK) { ZLOGE("Remove data failed."); - CloseStoreWhenCorrupted(key.intention, static_cast(status)); + CloseStoreWhenCorrupted(key.intention, status); return E_DB_ERROR; } return E_OK; @@ -552,7 +551,7 @@ int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) ZLOGE("Get store failed:%{public}s", key.intention.c_str()); return E_DB_ERROR; } - auto status = store->GetSummary(key, summary); + int32_t status = store->GetSummary(key, summary); if (status != E_OK) { ZLOGE("Store get summary failed:%{public}s", key.intention.c_str()); CloseStoreWhenCorrupted(key.intention, status); @@ -592,7 +591,7 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi } Runtime runtime; - auto res = store->GetRuntime(query.key, runtime); + int32_t res = store->GetRuntime(query.key, runtime); if (res == E_NOT_FOUND) { privilegeCache_[query.key] = privilege; ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str()); @@ -716,7 +715,7 @@ int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result) } Runtime runtime; - auto res = store->GetRuntime(query.key, runtime); + int32_t res = store->GetRuntime(query.key, runtime); if (res != E_OK) { ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); CloseStoreWhenCorrupted(key.intention, res); @@ -756,7 +755,7 @@ int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t ZLOGE("SetAppShareOption failed,shareOption already set:%{public}s", shareOptionTmp.c_str()); return E_SETTINGS_EXISTED; } - auto status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)); + int32_t status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)); if (status != E_OK) { ZLOGE("Store get unifiedData failed:%{public}d", status); CloseStoreWhenCorrupted(intention, status); @@ -781,8 +780,8 @@ int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); if (ret != E_OK) { ZLOGW("GetLocal failed:%{public}s", intention.c_str()); - CloseStoreWhenCorrupted(intention, static_cast(ret)); - return E_DB_ERROR; + CloseStoreWhenCorrupted(intention, ret); + return ret; } ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str()); shareOption = ShareOptionsUtil::GetEnumNum(appShareOption); @@ -809,7 +808,7 @@ int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) } UnifiedData unifiedData; - auto status = store->DeleteLocal(std::to_string(accessTokenIDEx)); + int32_t status = store->DeleteLocal(std::to_string(accessTokenIDEx)); if (status != E_OK) { ZLOGE("Store DeleteLocal failed:%{public}s, status:%{public}d", intention.c_str(), status); CloseStoreWhenCorrupted(intention, status); @@ -858,7 +857,7 @@ int32_t UdmfServiceImpl::QueryDataCommon( ZLOGE("Get store failed:%{public}s", intention.c_str()); return E_DB_ERROR; } - auto status = store->GetBatchData(dataPrefix, dataSet); + int32_t status = store->GetBatchData(dataPrefix, dataSet); if (status != E_OK) { ZLOGE("Get dataSet failed, dataPrefix: %{public}s, status:%{public}d.", dataPrefix.c_str(), status); CloseStoreWhenCorrupted(intention, status); @@ -1146,7 +1145,7 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptrPutSummary(udkey, summary); + int32_t status = store->PutSummary(udkey, summary); if (status != E_OK) { ZLOGE("Put summary failed:%{public}s, status:%{public}d", key.c_str(), status); CloseStoreWhenCorrupted(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status); @@ -1253,11 +1252,12 @@ bool UdmfServiceImpl::IsValidInput(const QueryOption &query, UnifiedData &unifie return true; } -void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, Status status) +void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, int32_t &status) { if (status == E_DB_CORRUPTED) { ZLOGE("Kv database corrupted, start to remove store"); StoreCache::GetInstance().RemoveStore(intention); + status = E_DB_ERROR; } } } // namespace UDMF diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index f8aed0684..457b1f92a 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -83,7 +83,7 @@ private: int32_t ValidateAndProcessRuntimeData(const std::vector &dataSet, std::shared_ptr runtime, std::vector &unifiedDataSet, const QueryOption &query, std::vector &deleteKeys); int32_t CheckAppId(std::shared_ptr runtime, const std::string &bundleName); - void CloseStoreWhenCorrupted(const std::string &intention, Status status); + void CloseStoreWhenCorrupted(const std::string &intention, int32_t &status); class Factory { public: Factory(); -- Gitee From 80f3778f061b76cea3e96737d3f3cf473116205a Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Sat, 5 Jul 2025 10:46:41 +0800 Subject: [PATCH 13/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I284287f9cbe93b7f62744b3101ca4f8c4c75458c --- .../service/test/udmf_service_impl_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp index df0427031..94a0689d3 100644 --- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp @@ -600,7 +600,7 @@ HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted001, TestSize.Level1) StoreCache::GetInstance().CloseStores(); auto store = StoreCache::GetInstance().GetStore(intention); EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); - Status status = UDMF::E_OK; + int32_t status = UDMF::E_OK; UdmfServiceImpl impl; impl.CloseStoreWhenCorrupted(intention, status); EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); @@ -617,7 +617,7 @@ HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted002, TestSize.Level1) StoreCache::GetInstance().CloseStores(); auto store = StoreCache::GetInstance().GetStore(intention); EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); - Status status = UDMF::E_DB_CORRUPTED; + int32_t status = UDMF::E_DB_CORRUPTED; UdmfServiceImpl impl; impl.CloseStoreWhenCorrupted(intention, status); EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 0); -- Gitee From 9875e730c93dcb7c06c726e8a15555ea7ddb9747 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Sat, 5 Jul 2025 11:10:02 +0800 Subject: [PATCH 14/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: Id49ae992d841cf53ad9cc7442515a494ad780087 --- .../test/mock/kv_store_nb_delegate_corruption_mock.cpp | 2 +- .../service/test/mock/kv_store_nb_delegate_corruption_mock.h | 2 +- .../service/test/mock/preprocess_utils_mock.cpp | 2 +- .../service/test/mock/preprocess_utils_mock.h | 2 +- .../service/udmf/store/runtime_store.cpp | 4 ++-- .../distributeddataservice/service/udmf/store/runtime_store.h | 2 +- .../distributeddataservice/service/udmf/store/store_cache.cpp | 2 +- .../distributeddataservice/service/udmf/store/store_cache.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp index 006a01df2..ecc6b4b34 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 diff --git a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h index 16176d2a3..7f7834822 100644 --- a/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h +++ b/services/distributeddataservice/service/test/mock/kv_store_nb_delegate_corruption_mock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp index e65ccc5d0..5e9372943 100644 --- a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp +++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h index c13e8590b..e79e2bb6c 100644 --- a/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h +++ b/services/distributeddataservice/service/test/mock/preprocess_utils_mock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 45e46563b..cd57d8801 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -450,7 +450,7 @@ bool RuntimeStore::Init() if (retStatus != DBStatus::OK) { ZLOGE("CloseKvStore fail, status: %{public}d.", static_cast(retStatus)); } - if (isCorrupted && (retStatus = delegateManager_->DeleteKvStore(storeId_)) != DBStatus::OK) { + if (isCorrupted_ && (retStatus = delegateManager_->DeleteKvStore(storeId_)) != DBStatus::OK) { ZLOGE("DeleteKvStore fail, status: %{public}d.", static_cast(retStatus)); } }; @@ -589,7 +589,7 @@ Status RuntimeStore::MarkWhenCorrupted(DistributedDB::DBStatus status) { if (status == INVALID_PASSWD_OR_CORRUPTED_DB) { ZLOGE("Kv database corrupted"); - isCorrupted = true; + isCorrupted_ = true; return E_DB_CORRUPTED; } return E_DB_ERROR; diff --git a/services/distributeddataservice/service/udmf/store/runtime_store.h b/services/distributeddataservice/service/udmf/store/runtime_store.h index c4457103e..214c6f15c 100644 --- a/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -65,7 +65,7 @@ private: const DevNameMap &deviceNameMap); Status PutSummary(const UnifiedData &data, std::vector &entries); Status MarkWhenCorrupted(DistributedDB::DBStatus status); - bool isCorrupted = false; + bool isCorrupted_ = false; }; } // namespace UDMF } // namespace OHOS diff --git a/services/distributeddataservice/service/udmf/store/store_cache.cpp b/services/distributeddataservice/service/udmf/store/store_cache.cpp index 30ae5c7a1..acc6bf716 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -92,7 +92,7 @@ void StoreCache::CloseStores() stores_.Clear(); } -void StoreCache::RemoveStore(std::string intention) +void StoreCache::RemoveStore(const std::string &intention) { ZLOGI("RemoveStore, intention:%{public}s", intention.c_str()); int foregroundUserId = 0; diff --git a/services/distributeddataservice/service/udmf/store/store_cache.h b/services/distributeddataservice/service/udmf/store/store_cache.h index b71481dbe..a8307f0a2 100644 --- a/services/distributeddataservice/service/udmf/store/store_cache.h +++ b/services/distributeddataservice/service/udmf/store/store_cache.h @@ -28,7 +28,7 @@ public: static StoreCache &GetInstance(); void SetThreadPool(std::shared_ptr executors); void CloseStores(); - void RemoveStore(std::string intention); + void RemoveStore(const std::string &intention); private: StoreCache() {} -- Gitee From 111b5de5c77b38237da19e410eccb8e8faff9eb3 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Sat, 5 Jul 2025 11:13:15 +0800 Subject: [PATCH 15/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: Ie5125f470434581e4a093093c0f2067e75057718 --- .../service/test/udmf_run_time_store_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp index 53dd9d421..1c92a86a6 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -741,7 +741,7 @@ HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted001, TestSize.Level1) DistributedDB::DBStatus status = DistributedDB::DBStatus::OK; auto store = std::make_shared(STORE_ID); store->MarkWhenCorrupted(status); - EXPECT_FALSE(store->isCorrupted); + EXPECT_FALSE(store->isCorrupted_); } /** @@ -755,7 +755,7 @@ HWTEST_F(UdmfRunTimeStoreTest, MarkWhenCorrupted002, TestSize.Level1) DistributedDB::DBStatus status = DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB; auto store = std::make_shared(STORE_ID); store->MarkWhenCorrupted(status); - EXPECT_TRUE(store->isCorrupted); + EXPECT_TRUE(store->isCorrupted_); } }; // namespace DistributedDataTest }; // namespace OHOS::Test \ No newline at end of file -- Gitee From 52e0780cc9354dbfd11ac0dada8bca628c8b6c2d Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Sat, 5 Jul 2025 14:19:48 +0800 Subject: [PATCH 16/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: Ib466b2a19332d321f15164f94a828a2faeb20b8b --- .../service/test/udmf_service_impl_test.cpp | 5 ++- .../service/udmf/udmf_service_impl.cpp | 38 +++++++++++-------- .../service/udmf/udmf_service_impl.h | 3 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp index 94a0689d3..735df7c17 100644 --- a/services/distributeddataservice/service/test/udmf_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/udmf_service_impl_test.cpp @@ -602,7 +602,7 @@ HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted001, TestSize.Level1) EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); int32_t status = UDMF::E_OK; UdmfServiceImpl impl; - impl.CloseStoreWhenCorrupted(intention, status); + impl.HandleDbError(intention, status); EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); } @@ -619,8 +619,9 @@ HWTEST_F(UdmfServiceImplTest, CloseStoreWhenCorrupted002, TestSize.Level1) EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 1); int32_t status = UDMF::E_DB_CORRUPTED; UdmfServiceImpl impl; - impl.CloseStoreWhenCorrupted(intention, status); + impl.HandleDbError(intention, status); EXPECT_EQ(StoreCache::GetInstance().stores_.Size(), 0); + EXPECT_EQ(status, UDMF::E_DB_ERROR); } }; // namespace DistributedDataTest }; // namespace OHOS::Test diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 66f83afa0..13718ddd6 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -154,7 +154,7 @@ int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData int32_t status = store->Put(unifiedData); if (status != E_OK) { ZLOGE("Put unified data failed:%{public}s, status:%{public}d", intention.c_str(), status); - CloseStoreWhenCorrupted(intention, status); + HandleDbError(intention, status); return E_DB_ERROR; } key = unifiedData.GetRuntime()->key.GetUnifiedKey(); @@ -220,7 +220,7 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni int32_t res = store->Get(query.key, unifiedData); if (res != E_OK) { ZLOGE("Get data failed,res:%{public}d,key:%{public}s", res, query.key.c_str()); - CloseStoreWhenCorrupted(key.intention, res); + HandleDbError(key.intention, res); return res; } @@ -417,7 +417,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi int32_t res = store->Get(query.key, data); if (res != E_OK) { ZLOGE("Get data failed:%{public}s", key.intention.c_str()); - CloseStoreWhenCorrupted(key.intention, res); + HandleDbError(key.intention, res); return res; } if (data.IsEmpty()) { @@ -439,7 +439,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi PreProcessUtils::SetRecordUid(unifiedData); if ((res = store->Update(unifiedData)) != E_OK) { ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); - CloseStoreWhenCorrupted(key.intention, res); + HandleDbError(key.intention, res); return res; } return E_OK; @@ -499,7 +499,7 @@ int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vectorDeleteBatch(deleteKeys); if (status != E_OK) { ZLOGE("Remove data failed."); - CloseStoreWhenCorrupted(key.intention, status); + HandleDbError(key.intention, status); return E_DB_ERROR; } return E_OK; @@ -554,7 +554,7 @@ int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary) int32_t status = store->GetSummary(key, summary); if (status != E_OK) { ZLOGE("Store get summary failed:%{public}s", key.intention.c_str()); - CloseStoreWhenCorrupted(key.intention, status); + HandleDbError(key.intention, status); return E_DB_ERROR; } return E_OK; @@ -599,14 +599,14 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi } if (res != E_OK) { ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); - CloseStoreWhenCorrupted(key.intention, res); + HandleDbError(key.intention, res); return res; } runtime.privileges.emplace_back(privilege); res = store->PutRuntime(query.key, runtime); if (res != E_OK) { ZLOGE("Update runtime failed, res:%{public}d, key:%{public}s", res, query.key.c_str()); - CloseStoreWhenCorrupted(key.intention, res); + HandleDbError(key.intention, res); } return res; } @@ -718,7 +718,7 @@ int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result) int32_t res = store->GetRuntime(query.key, runtime); if (res != E_OK) { ZLOGE("Get runtime failed, res:%{public}d, key:%{public}s.", res, query.key.c_str()); - CloseStoreWhenCorrupted(key.intention, res); + HandleDbError(key.intention, res); return E_DB_ERROR; } @@ -758,7 +758,7 @@ int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t int32_t status = store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)); if (status != E_OK) { ZLOGE("Store get unifiedData failed:%{public}d", status); - CloseStoreWhenCorrupted(intention, status); + HandleDbError(intention, status); return E_DB_ERROR; } return E_OK; @@ -780,7 +780,7 @@ int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); if (ret != E_OK) { ZLOGW("GetLocal failed:%{public}s", intention.c_str()); - CloseStoreWhenCorrupted(intention, ret); + HandleDbError(intention, ret); return ret; } ZLOGI("GetLocal ok intention:%{public}s,appShareOption:%{public}s", intention.c_str(), appShareOption.c_str()); @@ -811,7 +811,7 @@ int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) int32_t status = store->DeleteLocal(std::to_string(accessTokenIDEx)); if (status != E_OK) { ZLOGE("Store DeleteLocal failed:%{public}s, status:%{public}d", intention.c_str(), status); - CloseStoreWhenCorrupted(intention, status); + HandleDbError(intention, status); return E_DB_ERROR; } return E_OK; @@ -860,7 +860,7 @@ int32_t UdmfServiceImpl::QueryDataCommon( int32_t status = store->GetBatchData(dataPrefix, dataSet); if (status != E_OK) { ZLOGE("Get dataSet failed, dataPrefix: %{public}s, status:%{public}d.", dataPrefix.c_str(), status); - CloseStoreWhenCorrupted(intention, status); + HandleDbError(intention, status); return E_DB_ERROR; } return E_OK; @@ -1148,7 +1148,7 @@ int32_t UdmfServiceImpl::SetDelayInfo(const DataLoadInfo &dataLoadInfo, sptrPutSummary(udkey, summary); if (status != E_OK) { ZLOGE("Put summary failed:%{public}s, status:%{public}d", key.c_str(), status); - CloseStoreWhenCorrupted(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status); + HandleDbError(UD_INTENTION_MAP.at(UD_INTENTION_DRAG), status); return E_DB_ERROR; } return E_OK; @@ -1252,11 +1252,19 @@ bool UdmfServiceImpl::IsValidInput(const QueryOption &query, UnifiedData &unifie return true; } -void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, int32_t &status) +void UdmfServiceImpl::CloseStoreWhenCorrupted(const std::string &intention, int32_t status) { if (status == E_DB_CORRUPTED) { ZLOGE("Kv database corrupted, start to remove store"); StoreCache::GetInstance().RemoveStore(intention); + } +} + +void UdmfServiceImpl::HandleDbError(const std::string &intention, int32_t &status) +{ + CloseStoreWhenCorrupted(intention, status); + if (status == E_DB_CORRUPTED) { + // reset status to E_DB_ERROR status = E_DB_ERROR; } } diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.h b/services/distributeddataservice/service/udmf/udmf_service_impl.h index 457b1f92a..87d0af224 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -83,7 +83,8 @@ private: int32_t ValidateAndProcessRuntimeData(const std::vector &dataSet, std::shared_ptr runtime, std::vector &unifiedDataSet, const QueryOption &query, std::vector &deleteKeys); int32_t CheckAppId(std::shared_ptr runtime, const std::string &bundleName); - void CloseStoreWhenCorrupted(const std::string &intention, int32_t &status); + void CloseStoreWhenCorrupted(const std::string &intention, int32_t status); + void HandleDbError(const std::string &intention, int32_t &status); class Factory { public: Factory(); -- Gitee From 5dfda11c0a7c2888242a2dfd6a761f3487dda627 Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Sat, 5 Jul 2025 14:23:10 +0800 Subject: [PATCH 17/17] fix-db-corruption Signed-off-by: wenjinchao Change-Id: I9cecdb13c359cb2b21e50077f19800bf1196bf20 --- .../distributeddataservice/service/udmf/udmf_service_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp index 13718ddd6..3cc61d68c 100644 --- a/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -440,7 +440,7 @@ int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifi if ((res = store->Update(unifiedData)) != E_OK) { ZLOGE("Unified data update failed:%{public}s", key.intention.c_str()); HandleDbError(key.intention, res); - return res; + return E_DB_ERROR; } return E_OK; } -- Gitee