From aa1d5f656677b9b0d3711fe9a0470c57d59e4f4a Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 17:22:13 +0800 Subject: [PATCH 1/2] fix db corruption Signed-off-by: wenjinchao Change-Id: Ia318f5d4cd4f4adf097d6f84cd6e054970272169 --- .../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 + 14 files changed, 1367 insertions(+), 44 deletions(-) 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/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index eb5bd16e4..55a02b818 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -2099,6 +2099,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 @@ -2127,6 +2215,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 71b8d5c25..31ccbd13c 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -706,5 +706,33 @@ HWTEST_F(UdmfRunTimeStoreTest, GetRuntime002, TestSize.Level1) auto status = store->GetRuntime(key, outRuntime); EXPECT_EQ(status, E_NOT_FOUND); } + +/** +* @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 87db1b302e62d0d9f5a97f26956ec1dead313fba Mon Sep 17 00:00:00 2001 From: wenjinchao Date: Fri, 4 Jul 2025 17:26:10 +0800 Subject: [PATCH 2/2] fix db corruption Signed-off-by: wenjinchao Change-Id: Idcd2497bff8c21d6fc0a5666a4ca66a95709da27 --- .../service/test/udmf_run_time_store_test.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) 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 31ccbd13c..80ff03d8e 100644 --- a/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -707,6 +707,35 @@ HWTEST_F(UdmfRunTimeStoreTest, GetRuntime002, TestSize.Level1) EXPECT_EQ(status, E_NOT_FOUND); } +/** +* @tc.name: OnAccountChanged001 +* @tc.desc: Abnormal testcase of OnAccountChanged +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, OnAccountChanged001, TestSize.Level1) +{ + RuntimeStoreAccountObserver observer; + const AccountEventInfo eventInfo = { + .status = AccountStatus::DEVICE_ACCOUNT_DELETE + }; + DistributedData::StoreMetaData metaData; + uint32_t token = IPCSkeleton::GetSelfTokenID(); + metaData.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + metaData.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + metaData.user = eventInfo.userId; + metaData.tokenId = token; + metaData.securityLevel = DistributedKv::SecurityLevel::S1; + metaData.area = DistributedKv::Area::EL1; + metaData.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; + metaData.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(metaData); + std::string userPath = metaData.dataDir.append("/").append(eventInfo.userId); + observer.OnAccountChanged(eventInfo, 0); + EXPECT_EQ(access(userPath.c_str(), F_OK), -1); + SetSelfTokenID(0); + observer.OnAccountChanged(eventInfo, 0); +} + /** * @tc.name: MarkWhenCorrupted001 * @tc.desc: Normal testcase of MarkWhenCorrupted -- Gitee