diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp index 56d347e2e79d21cee509a975b1f35863288d5b72..fc509ff744f1b62964f286a87b3a6dc922ff78ed 100644 --- a/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp @@ -39,6 +39,9 @@ using DmAdapter = DistributedData::DeviceManagerAdapter; using DBManager = DistributedDB::KvStoreDelegateManager; constexpr const int ALIGN_WIDTH = 8; constexpr const char *DEFAULT_USERID = "0"; +constexpr const char *DATA_OBJECT_STORE_ID = "distributedObject_"; +constexpr const char *UDMF_STORE_ID = "drag"; + std::shared_ptr RouteHeadHandlerImpl::Create(const ExtendInfo &info) { auto handler = std::make_shared(info); @@ -101,13 +104,13 @@ DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize { ZLOGD("begin"); headSize = 0; - if (appId_ == Bootstrap::GetInstance().GetProcessLabel() && storeId_ == Bootstrap::GetInstance().GetMetaDBName()) { + if (appId_ == Bootstrap::GetInstance().GetProcessLabel() && storeId_ != UDMF_STORE_ID && + storeId_ != DATA_OBJECT_STORE_ID) { ZLOGI("meta data permitted"); return DistributedDB::OK; } if (!DmAdapter::GetInstance().IsOHOSType(session_.targetDeviceId)) { - ZLOGD("devicdId:%{public}s is not oh type", - Anonymous::Change(session_.targetDeviceId).c_str()); + ZLOGD("deviceId:%{public}s is not oh type", Anonymous::Change(session_.targetDeviceId).c_str()); if (appId_.empty()) { return DistributedDB::DB_ERROR; } @@ -121,7 +124,10 @@ DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize auto peerCap = UpgradeManager::GetInstance().GetCapability(session_.targetDeviceId, flag); if (!flag) { ZLOGI("get peer cap failed"); - return DistributedDB::DB_ERROR; + return (appId_ == Bootstrap::GetInstance().GetProcessLabel() && + (storeId_ == UDMF_STORE_ID || storeId_ == DATA_OBJECT_STORE_ID)) + ? DistributedDB::OK + : DistributedDB::DB_ERROR; } if ((appId_ == Bootstrap::GetInstance().GetProcessLabel() && storeId_ != Bootstrap::GetInstance().GetMetaDBName() && peerCap.version < CapMetaData::UDMF_AND_OBJECT_VERSION) @@ -281,17 +287,15 @@ bool RouteHeadHandlerImpl::ParseHeadDataLen(const uint8_t *data, uint32_t totalL ZLOGI("other type device received. device:%{public}s", Anonymous::Change(device).c_str()); return true; } - - bool flag = false; - auto peerCap = UpgradeManager::GetInstance().GetCapability(device, flag); - if (!flag) { - ZLOGI("get peer cap failed"); - return false; - } - if (appId_ == Bootstrap::GetInstance().GetProcessLabel() && storeId_ != Bootstrap::GetInstance().GetMetaDBName() - && peerCap.version < CapMetaData::UDMF_AND_OBJECT_VERSION) { - ZLOGI("ignore older version device for udmf or object"); - return false; + + if (appId_ == Bootstrap::GetInstance().GetProcessLabel() && + (storeId_ == UDMF_STORE_ID || storeId_ == DATA_OBJECT_STORE_ID)) { + bool flag = false; + auto peerCap = UpgradeManager::GetInstance().GetCapability(device, flag); + if (flag && peerCap.version < CapMetaData::UDMF_AND_OBJECT_VERSION) { + ZLOGI("get peer cap success, peerCap's version is %{public}d, less than 3", peerCap.version); + return false; + } } RouteHead head = { 0 }; diff --git a/services/distributeddataservice/service/object/BUILD.gn b/services/distributeddataservice/service/object/BUILD.gn index 35412b7339eb950897272089f118acf3bffbec75..7ebc673313d939321486b3932fbabfe1ffd857b4 100644 --- a/services/distributeddataservice/service/object/BUILD.gn +++ b/services/distributeddataservice/service/object/BUILD.gn @@ -18,6 +18,7 @@ config("object_public_config") { include_dirs = [ "${data_service_path}/service/common", + "${data_service_path}/service/matrix/include", "${data_service_path}/adapter/include/communicator", "${data_service_path}/adapter/include/utils", ] diff --git a/services/distributeddataservice/service/object/include/object_manager.h b/services/distributeddataservice/service/object/include/object_manager.h index a5026a5d0293799115bce2972454ebada6e23dfd..eb61ef3f1d1aa335ace36fa1b734676c691f15d2 100644 --- a/services/distributeddataservice/service/object/include/object_manager.h +++ b/services/distributeddataservice/service/object/include/object_manager.h @@ -21,6 +21,7 @@ #include "device_manager_adapter.h" #include "kv_store_delegate_manager.h" #include "kvstore_sync_callback.h" +#include "metadata/store_meta_data.h" #include "object_asset_loader.h" #include "object_callback.h" #include "object_callback_proxy.h" @@ -64,6 +65,7 @@ class ObjectStoreManager { public: using DmAdaper = OHOS::DistributedData::DeviceManagerAdapter; using UriToSnapshot = std::shared_ptr>>; + using StoreMetaData = OHOS::DistributedData::StoreMetaData; enum RestoreStatus : int32_t { NONE = 0, @@ -159,6 +161,7 @@ private: DistributedDB::KvStoreNbDelegate *OpenObjectKvStore(); void FlushClosedStore(); void Close(); + void ForceClose(); int32_t SetSyncStatus(bool status); int32_t SaveToStore(const std::string &appId, const std::string &sessionId, const std::string &toDeviceId, const ObjectRecord &data); @@ -171,6 +174,8 @@ private: void ProcessSyncCallback(const std::map &results, const std::string &appId, const std::string &sessionId, const std::string &deviceId); void SaveUserToMeta(); + bool IsNeedMetaSync(const StoreMetaData &meta, const std::vector &networkIds); + int32_t DoSync(const std::string &prefix, const std::vector &deviceList, uint64_t sequenceId); std::string GetCurrentUser(); void DoNotify(uint32_t tokenId, const CallbackInfo& value, const std::map& data, bool allReady); @@ -212,15 +217,15 @@ private: return std::string(USERID) + SEPERATOR + userId + SEPERATOR + appId + SEPERATOR + DmAdaper::GetInstance().GetLocalDevice().udid; }; - std::recursive_mutex kvStoreMutex_; + mutable std::shared_timed_mutex rwMutex_; std::shared_ptr kvStoreDelegateManager_ = nullptr; DistributedDB::KvStoreNbDelegate *delegate_ = nullptr; ObjectDataListener objectDataListener_; sptr objectAssetsRecvListener_ = nullptr; sptr objectAssetsSendListener_ = nullptr; - uint32_t syncCount_ = 0; + std::atomic syncCount_{ 0 }; std::string userId_; - std::atomic isSyncing_ = false; + std::atomic isSyncing_{ false }; ConcurrentMap callbacks_; ConcurrentMap processCallbacks_; std::shared_ptr executors_; diff --git a/services/distributeddataservice/service/object/src/object_manager.cpp b/services/distributeddataservice/service/object/src/object_manager.cpp index 8e08a4cf67a53098a7db738dd50eb244552ca2d3..e0665f7407cd9f57eaa2b9cf7203c3eb698b9911 100644 --- a/services/distributeddataservice/service/object/src/object_manager.cpp +++ b/services/distributeddataservice/service/object/src/object_manager.cpp @@ -26,6 +26,9 @@ #include "common/string_utils.h" #include "datetime_ex.h" #include "distributed_file_daemon_manager.h" +#include "device_matrix.h" +#include "ipc_skeleton.h" +#include "metadata/capability_meta_data.h" #include "kvstore_utils.h" #include "log_print.h" #include "metadata/meta_data_manager.h" @@ -44,9 +47,12 @@ using Account = OHOS::DistributedData::AccountDelegate; using AccessTokenKit = Security::AccessToken::AccessTokenKit; using ValueProxy = OHOS::DistributedData::ValueProxy; using DistributedFileDaemonManager = Storage::DistributedFile::DistributedFileDaemonManager; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; + constexpr const char *SAVE_INFO = "p_###SAVEINFO###"; constexpr int32_t PROGRESS_MAX = 100; constexpr int32_t PROGRESS_INVALID = -1; +constexpr uint32_t LOCK_TIMEOUT = 3600; // second ObjectStoreManager::ObjectStoreManager() { ZLOGI("ObjectStoreManager construct"); @@ -319,7 +325,7 @@ int32_t ObjectStoreManager::Clear() result = RevokeSaveToStore(""); callbacks_.Clear(); processCallbacks_.Clear(); - Close(); + ForceClose(); return result; } @@ -571,6 +577,34 @@ void ObjectStoreManager::ComputeStatus(const std::string& objectKey, const SaveI }); } +bool ObjectStoreManager::IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids) +{ + bool isAfterMeta = false; + for (const auto &uuid : uuids) { + auto metaData = meta; + metaData.deviceId = uuid; + CapMetaData capMeta; + auto capKey = CapMetaRow::GetKeyFor(uuid); + bool flag = !MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) || + !MetaDataManager::GetInstance().LoadMeta(metaData.GetKeyWithoutPath(), metaData); + if (flag) { + isAfterMeta = true; + break; + } + auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid); + if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) { + isAfterMeta = true; + break; + } + auto [existLocal, localMask] = DeviceMatrix::GetInstance().GetMask(uuid); + if ((localMask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) { + isAfterMeta = true; + break; + } + } + return isAfterMeta; +} + void ObjectStoreManager::NotifyDataChanged(const std::map& data, const SaveInfo& saveInfo) { for (auto const& [objectKey, results] : data) { @@ -836,7 +870,7 @@ int32_t ObjectStoreManager::Open() ZLOGE("Kvstore delegate manager not init"); return OBJECT_INNER_ERROR; } - std::lock_guard lock(kvStoreMutex_); + std::unique_lock lock(rwMutex_); if (delegate_ == nullptr) { delegate_ = OpenObjectKvStore(); if (delegate_ == nullptr) { @@ -847,25 +881,44 @@ int32_t ObjectStoreManager::Open() ZLOGI("Open object kvstore success"); } else { syncCount_++; - ZLOGI("Object kvstore syncCount: %{public}d", syncCount_); + ZLOGI("Object kvstore syncCount: %{public}d", syncCount_.load()); } return OBJECT_SUCCESS; } -void ObjectStoreManager::Close() +void ObjectStoreManager::ForceClose() { - std::lock_guard lock(kvStoreMutex_); + std::unique_lock lock(rwMutex_, std::chrono::seconds(LOCK_TIMEOUT)); if (delegate_ == nullptr) { return; } - int32_t taskCount = delegate_->GetTaskCount(); + auto status = kvStoreDelegateManager_->CloseKvStore(delegate_); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("CloseKvStore fail %{public}d", status); + return; + } + delegate_ = nullptr; + isSyncing_ = false; + syncCount_ = 0; +} + +void ObjectStoreManager::Close() +{ + int32_t taskCount = 0; + { + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + return; + } + taskCount = delegate_->GetTaskCount(); + } if (taskCount > 0 && syncCount_ == 1) { CloseAfterMinute(); ZLOGW("Store is busy, close after a minute, task count: %{public}d", taskCount); return; } syncCount_--; - ZLOGI("closed a store, syncCount = %{public}d", syncCount_); + ZLOGI("closed a store, syncCount = %{public}d", syncCount_.load()); FlushClosedStore(); } @@ -875,7 +928,6 @@ void ObjectStoreManager::SyncCompleted( std::string userId; SequenceSyncManager::Result result = SequenceSyncManager::GetInstance()->Process(sequenceId, results, userId); if (result == SequenceSyncManager::SUCCESS_USER_HAS_FINISHED && userId == userId_) { - std::lock_guard lock(kvStoreMutex_); SetSyncStatus(false); FlushClosedStore(); } @@ -891,10 +943,10 @@ void ObjectStoreManager::SyncCompleted( } } } - + void ObjectStoreManager::FlushClosedStore() { - std::lock_guard lock(kvStoreMutex_); + std::unique_lock lock(rwMutex_); if (!isSyncing_ && syncCount_ == 0 && delegate_ != nullptr) { ZLOGD("close store"); auto status = kvStoreDelegateManager_->CloseKvStore(delegate_); @@ -913,14 +965,17 @@ void ObjectStoreManager::FlushClosedStore() void ObjectStoreManager::ProcessOldEntry(const std::string &appId) { std::vector entries; - auto status = delegate_->GetEntries(std::vector(appId.begin(), appId.end()), entries); - if (status == DistributedDB::DBStatus::NOT_FOUND) { - ZLOGI("Get old entries empty, bundleName: %{public}s", appId.c_str()); - return; - } - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("Get old entries failed, bundleName: %{public}s, status %{public}d", appId.c_str(), status); - return; + { + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("delegate is nullptr."); + return; + } + auto status = delegate_->GetEntries(std::vector(appId.begin(), appId.end()), entries); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("Get old entries failed, bundleName: %{public}s, status %{public}d", appId.c_str(), status); + return; + } } std::map sessionIds; int64_t oldestTime = 0; @@ -975,12 +1030,19 @@ int32_t ObjectStoreManager::SaveToStore(const std::string &appId, const std::str entry.value = item.second; entries.emplace_back(entry); } - auto status = delegate_->PutBatch(entries); - if (status != DistributedDB::DBStatus::OK) { - ZLOGE("PutBatch failed, bundleName: %{public}s, sessionId: %{public}s, dstNetworkId: %{public}s, " - "status: %{public}d", - appId.c_str(), Anonymous::Change(sessionId).c_str(), Anonymous::Change(toDeviceId).c_str(), status); - return status; + { + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("delegate is nullptr."); + return E_DB_ERROR; + } + auto status = delegate_->PutBatch(entries); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("PutBatch failed, bundleName: %{public}s, sessionId: %{public}s, dstNetworkId: %{public}s, " + "status: %{public}d", + appId.c_str(), Anonymous::Change(sessionId).c_str(), Anonymous::Change(toDeviceId).c_str(), status); + return status; + } } ZLOGI("PutBatch success, bundleName: %{public}s, sessionId: %{public}s, dstNetworkId: %{public}s, " "count: %{public}zu", @@ -1006,10 +1068,35 @@ int32_t ObjectStoreManager::SyncOnStore( return OBJECT_SUCCESS; } uint64_t sequenceId = SequenceSyncManager::GetInstance()->AddNotifier(userId_, callback); + + int32_t id = AccountDelegate::GetInstance()->GetUserByToken(IPCSkeleton::GetCallingFullTokenID()); + StoreMetaData meta = StoreMetaData(std::to_string(id), Bootstrap::GetInstance().GetProcessLabel(), + DistributedObject::ObjectCommon::OBJECTSTORE_DB_STOREID); + auto uuids = DmAdapter::GetInstance().ToUUID(syncDevices); + bool isNeedMetaSync = IsNeedMetaSync(meta, uuids); + if (!isNeedMetaSync) { + return DoSync(prefix, syncDevices, sequenceId); + } + bool result = MetaDataManager::GetInstance().Sync(uuids, [this, prefix, syncDevices, sequenceId](auto &results) { + auto status = DoSync(prefix, syncDevices, sequenceId); + ZLOGI("Store sync after meta sync end, status:%{public}d", status); + }); + ZLOGI("prefix:%{public}s, meta sync end, result:%{public}d", Anonymous::Change(prefix).c_str(), result); + return result ? OBJECT_SUCCESS : DoSync(prefix, syncDevices, sequenceId); +} + +int32_t ObjectStoreManager::DoSync(const std::string &prefix, const std::vector &deviceList, + uint64_t sequenceId) +{ + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("db store was closed."); + return E_DB_ERROR; + } DistributedDB::Query dbQuery = DistributedDB::Query::Select(); dbQuery.PrefixKey(std::vector(prefix.begin(), prefix.end())); ZLOGI("Start sync data, sequenceId: 0x%{public}" PRIx64 "", sequenceId); - auto status = delegate_->Sync(syncDevices, DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY, + auto status = delegate_->Sync(deviceList, DistributedDB::SyncMode::SYNC_MODE_PUSH_ONLY, [this, sequenceId](const std::map &devicesMap) { ZLOGI("Sync data finished, sequenceId: 0x%{public}" PRIx64 "", sequenceId); std::map result; @@ -1031,7 +1118,6 @@ int32_t ObjectStoreManager::SyncOnStore( int32_t ObjectStoreManager::SetSyncStatus(bool status) { - std::lock_guard lock(kvStoreMutex_); isSyncing_ = status; return OBJECT_SUCCESS; } @@ -1039,6 +1125,11 @@ int32_t ObjectStoreManager::SetSyncStatus(bool status) int32_t ObjectStoreManager::RevokeSaveToStore(const std::string &prefix) { std::vector entries; + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("db store was closed."); + return E_DB_ERROR; + } auto status = delegate_->GetEntries(std::vector(prefix.begin(), prefix.end()), entries); if (status == DistributedDB::DBStatus::NOT_FOUND) { ZLOGI("Get entries empty, prefix: %{public}s", Anonymous::Change(prefix).c_str()); @@ -1071,6 +1162,11 @@ int32_t ObjectStoreManager::RetrieveFromStore(const std::string &appId, const st { std::vector entries; std::string prefix = GetPrefixWithoutDeviceId(appId, sessionId); + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("db store was closed."); + return E_DB_ERROR; + } auto status = delegate_->GetEntries(std::vector(prefix.begin(), prefix.end()), entries); if (status == DistributedDB::DBStatus::NOT_FOUND) { ZLOGI("Get entries empty, prefix: %{public}s, status: %{public}d", Anonymous::Change(prefix).c_str(), status); diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index c93164adb5e0407fdace0913393d3e7c24853102..276c412d9041280666dc23da3b34e79de80d991c 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -862,6 +862,72 @@ ohos_unittest("ObjectManagerTest") { ] } +ohos_unittest("ObjectManagerMockTest") { + module_out_path = module_output_path + sources = [ + "${data_service_path}/app/src/kvstore_meta_manager.cpp", + "${data_service_path}/service/common/common_types_utils.cpp", + "${data_service_path}/service/common/value_proxy.cpp", + "../object/src/object_asset_loader.cpp", + "../object/src/object_asset_machine.cpp", + "../object/src/object_callback_proxy.cpp", + "../object/src/object_data_listener.cpp", + "../object/src/object_dms_handler.cpp", + "../object/src/object_manager.cpp", + "../object/src/object_service_impl.cpp", + "../object/src/object_service_stub.cpp", + "../object/src/object_snapshot.cpp", + "../object/src/object_types_utils.cpp", + "mock/device_manager_adapter_mock.cpp", + "mock/kv_store_nb_delegate_mock.cpp", + "object_manager_mock_test.cpp", + "mock/meta_data_manager_mock.cpp", + "mock/device_matrix_mock.cpp", + ] + + include_dirs = [ + "${data_service_path}/adapter/include/utils", + "${data_service_path}/app/src", + "${data_service_path}/service/common", + "${data_service_path}/service/test/mock", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", + "access_token:libtokenid_sdk", + "c_utils:utils", + "data_object:distributeddataobject_impl", + "data_object:data_object_inner", + "dataclassification:data_transit_mgr", + "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "dmsfwk:distributed_sdk", + "googletest:gmock_main", + "hilog:libhilog", + "hisysevent:libhisysevent", + "ipc:ipc_core", + "cJSON:cjson", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "kv_store:distributeddb", + "relational_store:native_rdb", + "safwk:system_ability_fwk", + ] + + deps = [ + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] +} + ohos_unittest("ObjectSnapshotTest") { module_out_path = module_output_path sources = [ @@ -2240,6 +2306,7 @@ group("unittest") { ":ObjectDmsHandlerTest", ":ObjectManagerTest", ":ObjectSnapshotTest", + ":ObjectManagerMockTest", ] } diff --git a/services/distributeddataservice/service/test/kvdb_general_store_abnormal_test.cpp b/services/distributeddataservice/service/test/kvdb_general_store_abnormal_test.cpp index 7be5d9029e7f4edd5adaec52996439e3ceeb499d..1e78eb6abb82c322e82ed94c385763910a20c86b 100644 --- a/services/distributeddataservice/service/test/kvdb_general_store_abnormal_test.cpp +++ b/services/distributeddataservice/service/test/kvdb_general_store_abnormal_test.cpp @@ -127,16 +127,19 @@ HWTEST_F(KVDBGeneralStoreAbnormalTest, GetDBOptionTest001, TestSize.Level0) HWTEST_F(KVDBGeneralStoreAbnormalTest, SetEqualIdentifier, TestSize.Level0) { auto store = new (std::nothrow) KVDBGeneralStore(metaData_); - std::vector uuids{"uuidtest01"}; + std::vector uuids{ "uuidtest01" }; KvStoreNbDelegateMock mockDelegate; mockDelegate.taskCountMock_ = 1; store->delegate_ = &mockDelegate; EXPECT_NE(store->delegate_, nullptr); - EXPECT_CALL(*deviceManagerAdapterMock, ToUUID(testing::_)).WillOnce(testing::Return(uuids)); + EXPECT_CALL(*deviceManagerAdapterMock, ToUUID(testing::A>())) + .WillOnce(testing::Return(uuids)); auto uuids1 = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices()); - EXPECT_CALL(*deviceManagerAdapterMock, ToUUID(testing::_)).WillOnce(testing::Return(uuids)); + EXPECT_CALL(*deviceManagerAdapterMock, ToUUID(testing::A>())) + .WillOnce(testing::Return(uuids)); EXPECT_CALL(*deviceManagerAdapterMock, IsOHOSType("uuidtest01")) - .WillOnce(testing::Return(false)).WillOnce(testing::Return(false)); + .WillOnce(testing::Return(false)) + .WillOnce(testing::Return(false)); store->SetEqualIdentifier(metaData_.appId, metaData_.storeId); EXPECT_EQ(uuids1, uuids); store->delegate_ = nullptr; diff --git a/services/distributeddataservice/service/test/mock/BUILD.gn b/services/distributeddataservice/service/test/mock/BUILD.gn index ce0a05278abb92ca72a0fa24e51ca940ae899dfd..3f49d2d2ef711f35529ccd6227b688e4e935a4e4 100644 --- a/services/distributeddataservice/service/test/mock/BUILD.gn +++ b/services/distributeddataservice/service/test/mock/BUILD.gn @@ -19,6 +19,7 @@ config("module_private_config") { include_dirs = [ "${data_service_path}/adapter/include/communicator", "${data_service_path}/service/kvdb", + "${data_service_path}/service/matrix/include/", "../../../framework/include/", "../../../service/rdb/", "./", @@ -48,6 +49,7 @@ ohos_static_library("distributeddata_mock_static") { "network_delegate_mock.cpp", "screen_lock_mock.cpp", "user_delegate_mock.cpp", + "device_matrix_mock.cpp", ] deps = [ "${data_service_path}/framework:distributeddatasvcfwk" ] diff --git a/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.cpp b/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.cpp index 7bc2b7e827787b60f71377ba7a571cac1ed3b3e5..5924460d94e1c786e50459857768bea1a201ac6d 100644 --- a/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.cpp +++ b/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.cpp @@ -34,6 +34,15 @@ std::vector OHOS::DistributedData::DeviceManagerAdapter::ToUUID(std return BDeviceManagerAdapter::deviceManagerAdapter->ToUUID(devices); } +std::vector OHOS::DistributedData::DeviceManagerAdapter::ToUUID(const std::vector &devices) +{ + if (BDeviceManagerAdapter::deviceManagerAdapter == nullptr) { + std::vector vec; + return vec; + } + return BDeviceManagerAdapter::deviceManagerAdapter->ToUUID(devices); +} + bool OHOS::DistributedData::DeviceManagerAdapter::IsOHOSType(const std::string &id) { if (BDeviceManagerAdapter::deviceManagerAdapter == nullptr) { diff --git a/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.h b/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.h index 2a47a5510f986afd8140d6d7173b07a92603e89d..d423327a76f1ada23316caed304e6688641afe71 100644 --- a/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.h +++ b/services/distributeddataservice/service/test/mock/device_manager_adapter_mock.h @@ -30,6 +30,7 @@ public: virtual std::vector GetRemoteDevices() = 0; virtual bool IsOHOSType(const std::string &) = 0; virtual std::vector ToUUID(std::vector) = 0; + virtual std::vector ToUUID(const std::vector &) = 0; virtual Status StartWatchDeviceChange(const AppDeviceChangeListener *, const PipeInfo &) = 0; virtual Status StopWatchDeviceChange(const AppDeviceChangeListener *, const PipeInfo &) = 0; virtual bool IsSameAccount(const AccessCaller &, const AccessCallee &) = 0; @@ -49,6 +50,7 @@ public: MOCK_METHOD(std::vector, GetRemoteDevices, ()); MOCK_METHOD(bool, IsOHOSType, (const std::string &)); MOCK_METHOD((std::vector), ToUUID, (std::vector)); + MOCK_METHOD((std::vector), ToUUID, (const std::vector &)); MOCK_METHOD(Status, StartWatchDeviceChange, (const AppDeviceChangeListener *, const PipeInfo &)); MOCK_METHOD(Status, StopWatchDeviceChange, (const AppDeviceChangeListener *, const PipeInfo &)); MOCK_METHOD(bool, IsSameAccount, (const AccessCaller &, const AccessCallee &)); diff --git a/services/distributeddataservice/service/test/mock/device_matrix_mock.cpp b/services/distributeddataservice/service/test/mock/device_matrix_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4cba3f3351f0e18a2163990654820e7f5ea7ecdb --- /dev/null +++ b/services/distributeddataservice/service/test/mock/device_matrix_mock.cpp @@ -0,0 +1,29 @@ +/* + * 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 "device_matrix_mock.h" + +namespace OHOS { +namespace DistributedData { +std::pair DeviceMatrix::GetRemoteMask(const std::string &device, DeviceMatrix::LevelType type) +{ + return BDeviceMatrix::deviceMatrix->GetRemoteMask(device, type); +} + +std::pair DeviceMatrix::GetMask(const std::string &device, DeviceMatrix::LevelType type) +{ + return BDeviceMatrix::deviceMatrix->GetMask(device, type); +} +} // namespace DistributedData +} // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/test/mock/device_matrix_mock.h b/services/distributeddataservice/service/test/mock/device_matrix_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..f67eb94ca23d8dd2ea61e15a8d19e3330fcd0d99 --- /dev/null +++ b/services/distributeddataservice/service/test/mock/device_matrix_mock.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DEVICE_MATRIX_MOCK_H +#define OHOS_DEVICE_MATRIX_MOCK_H + +#include + +#include "device_matrix.h" + +namespace OHOS::DistributedData { +class BDeviceMatrix { +public: + virtual std::pair GetMask(const std::string &, DeviceMatrix::LevelType); + virtual std::pair GetRemoteMask(const std::string &, DeviceMatrix::LevelType); + BDeviceMatrix() = default; + virtual ~BDeviceMatrix() = default; + static inline std::shared_ptr deviceMatrix = nullptr; +}; +class DeviceMatrixMock : public BDeviceMatrix { +public: + MOCK_METHOD((std::pair), GetMask, (const std::string &, DeviceMatrix::LevelType), (override)); + MOCK_METHOD((std::pair), GetRemoteMask, (const std::string &, DeviceMatrix::LevelType), (override)); +}; +} // namespace OHOS::DistributedData +#endif //OHOS_DEVICE_MATRIX_MOCK_H diff --git a/services/distributeddataservice/service/test/mock/meta_data_manager_mock.cpp b/services/distributeddataservice/service/test/mock/meta_data_manager_mock.cpp index 63476074063a4103b3d7d8019e0a98d5f467093e..fff2933da39d07a3ff484c570b15638dbce00355 100644 --- a/services/distributeddataservice/service/test/mock/meta_data_manager_mock.cpp +++ b/services/distributeddataservice/service/test/mock/meta_data_manager_mock.cpp @@ -40,6 +40,12 @@ bool OHOS::DistributedData::MetaDataManager::LoadMeta(const std::string &key, Se return BMetaDataManager::metaDataManager->LoadMeta(key, value, isLocal); } +bool OHOS::DistributedData::MetaDataManager::Sync(const std::vector &devices, + MetaDataManager::OnComplete complete, bool wait) +{ + return BMetaDataManager::metaDataManager->Sync(devices, complete, wait); +} + template<> bool OHOS::DistributedData::MetaDataManager::LoadMeta( const std::string &prefix, std::vector &values, bool isLocal) diff --git a/services/distributeddataservice/service/test/mock/meta_data_manager_mock.h b/services/distributeddataservice/service/test/mock/meta_data_manager_mock.h index 6db1bf93735376706386630ac2feb29a7db7a17b..42926ab9209b1728815318dd28165f6942192e01 100644 --- a/services/distributeddataservice/service/test/mock/meta_data_manager_mock.h +++ b/services/distributeddataservice/service/test/mock/meta_data_manager_mock.h @@ -26,6 +26,7 @@ namespace OHOS::DistributedData { class BMetaDataManager { public: virtual bool LoadMeta(const std::string &, Serializable &, bool) = 0; + virtual bool Sync(const std::vector &, MetaDataManager::OnComplete, bool) = 0; BMetaDataManager() = default; virtual ~BMetaDataManager() = default; static inline std::shared_ptr metaDataManager = nullptr; @@ -33,6 +34,7 @@ public: class MetaDataManagerMock : public BMetaDataManager { public: MOCK_METHOD(bool, LoadMeta, (const std::string &, Serializable &, bool), (override)); + MOCK_METHOD(bool, Sync, (const std::vector &, MetaDataManager::OnComplete, bool), (override)); }; template class BMetaData { diff --git a/services/distributeddataservice/service/test/object_manager_mock_test.cpp b/services/distributeddataservice/service/test/object_manager_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc03bec6fe7ec1e04fbe729a7bcee1347c65dc2a --- /dev/null +++ b/services/distributeddataservice/service/test/object_manager_mock_test.cpp @@ -0,0 +1,206 @@ +/* +* 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. +*/ + +#define LOG_TAG "ObjectManagerMockTest" +#include + +#include "device_manager_adapter_mock.h" +#include "device_matrix_mock.h" +#include "gtest/gtest.h" +#include "mock/meta_data_manager_mock.h" +#include "object_manager.h" + +using namespace OHOS::DistributedObject; +using namespace OHOS::DistributedData; +using namespace testing::ext; +using namespace testing; +using DeviceInfo = OHOS::AppDistributedKv::DeviceInfo; +using OnComplete = OHOS::DistributedData::MetaDataManager::OnComplete; + +namespace OHOS::Test { +namespace DistributedDataTest { +class ObjectManagerMockTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + metaDataManagerMock = std::make_shared(); + BMetaDataManager::metaDataManager = metaDataManagerMock; + metaDataMock = std::make_shared>(); + BMetaData::metaDataManager = metaDataMock; + devMgrAdapterMock = std::make_shared(); + BDeviceManagerAdapter::deviceManagerAdapter = devMgrAdapterMock; + deviceMatrixMock = std::make_shared(); + BDeviceMatrix::deviceMatrix = deviceMatrixMock; + } + static void TearDownTestCase(void) + { + metaDataManagerMock = nullptr; + BMetaDataManager::metaDataManager = nullptr; + metaDataMock = nullptr; + BMetaData::metaDataManager = nullptr; + devMgrAdapterMock = nullptr; + BDeviceManagerAdapter::deviceManagerAdapter = nullptr; + deviceMatrixMock = nullptr; + BDeviceMatrix::deviceMatrix = nullptr; + } + + static inline std::shared_ptr metaDataManagerMock = nullptr; + static inline std::shared_ptr> metaDataMock = nullptr; + static inline std::shared_ptr devMgrAdapterMock = nullptr; + static inline std::shared_ptr deviceMatrixMock = nullptr; + void SetUp(){}; + void TearDown(){}; +}; + +/** + * @tc.name: IsNeedMetaSync001 + * @tc.desc: Test IsNeedMetaSync when LoadMeta fails for CapMetaData. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ObjectManagerMockTest, IsNeedMetaSync001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + StoreMetaData meta; + meta.deviceId = "test_device_id"; + meta.user = "0"; + meta.storeId = "distributedObject_"; + meta.bundleName = "test_bundle"; + std::vector uuids = { "test_uuid" }; + + EXPECT_CALL(*metaDataManagerMock, LoadMeta(testing::_, testing::_, testing::_)).WillOnce(testing::Return(false)); + bool isNeedSync = manager->IsNeedMetaSync(meta, uuids); + EXPECT_EQ(isNeedSync, true); + EXPECT_CALL(*metaDataManagerMock, LoadMeta(testing::_, testing::_, testing::_)) + .WillOnce(testing::Return(true)) + .WillOnce(testing::Return(false)); + isNeedSync = manager->IsNeedMetaSync(meta, uuids); + EXPECT_EQ(isNeedSync, true); +} + +/** + * @tc.name: IsNeedMetaSync002 + * @tc.desc: Test IsNeedMetaSync when LoadMeta fails for StoreMetaData. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ObjectManagerMockTest, IsNeedMetaSync002, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + StoreMetaData meta; + meta.deviceId = "test_device_id"; + meta.user = "0"; + meta.storeId = "distributedObject_"; + meta.bundleName = "test_bundle"; + std::vector uuids = { "test_uuid" }; + + EXPECT_CALL(*metaDataManagerMock, LoadMeta(_, _, _)).WillRepeatedly(Return((true))); + EXPECT_CALL(*deviceMatrixMock, GetRemoteMask(_, _)) + .WillRepeatedly(Return(std::make_pair(true, DeviceMatrix::META_STORE_MASK))); + + bool result = manager->IsNeedMetaSync(meta, uuids); + EXPECT_EQ(result, true); +} + +/** + * @tc.name: IsNeedMetaSync003 + * @tc.desc: Test IsNeedMetaSync when LoadMeta fails for StoreMetaData. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ObjectManagerMockTest, IsNeedMetaSync003, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + StoreMetaData meta; + meta.deviceId = "test_device_id"; + meta.user = "0"; + meta.storeId = "distributedObject_"; + meta.bundleName = "test_bundle"; + std::vector uuids = { "test_uuid" }; + + EXPECT_CALL(*metaDataManagerMock, LoadMeta(_, _, _)).WillRepeatedly(Return(true)); + EXPECT_CALL(*deviceMatrixMock, GetRemoteMask(_, _)).WillOnce(Return(std::make_pair(true, 0))); + EXPECT_CALL(*deviceMatrixMock, GetMask(_, _)).WillOnce(Return(std::make_pair(true, DeviceMatrix::META_STORE_MASK))); + + bool result = manager->IsNeedMetaSync(meta, uuids); + EXPECT_EQ(result, true); + + EXPECT_CALL(*metaDataManagerMock, LoadMeta(_, _, _)).WillRepeatedly(Return(true)); + + EXPECT_CALL(*deviceMatrixMock, GetRemoteMask(_, _)).WillOnce(Return(std::make_pair(true, 0))); + + EXPECT_CALL(*deviceMatrixMock, GetMask(_, _)).WillOnce(Return(std::make_pair(true, 0))); + + result = manager->IsNeedMetaSync(meta, uuids); + EXPECT_EQ(result, false); +} + +/** + * @tc.name: SyncOnStore001 + * @tc.desc: Test SyncOnStore. + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(ObjectManagerMockTest, SyncOnStore001, TestSize.Level0) +{ + auto manager = ObjectStoreManager::GetInstance(); + std::function &results)> func; + func = [](const std::map &results) { return results; }; + std::string prefix = "ObjectManagerTest"; + StoreMetaData meta; + meta.deviceId = "test_device_id"; + meta.user = "0"; + meta.storeId = "distributedObject_"; + meta.bundleName = "test_bundle"; + std::vector uuids = { "test_uuid" }; + + // local device + { + std::vector localDeviceList = { "local" }; + auto result = manager->SyncOnStore(prefix, localDeviceList, func); + EXPECT_EQ(result, OBJECT_SUCCESS); + } + + // remote device. IsNeedMetaSync: true; Sync: true + { + std::vector remoteDeviceList = { "remote_device_1" }; + EXPECT_CALL(*devMgrAdapterMock, GetUuidByNetworkId(_)).WillRepeatedly(Return("mock_uuid")); + EXPECT_CALL(*devMgrAdapterMock, ToUUID(testing::A &>())) + .WillOnce(Return(std::vector{ "mock_uuid_1" })); + EXPECT_CALL(*metaDataManagerMock, LoadMeta(_, _, _)) + .WillOnce(testing::Return(false)) + .WillOnce(testing::Return(false)); + EXPECT_CALL(*metaDataManagerMock, Sync(_, _, _)).WillOnce(testing::Return(true)); + auto result = manager->SyncOnStore(prefix, remoteDeviceList, func); + EXPECT_EQ(result, OBJECT_SUCCESS); + } + + // remote device. IsNeedMetaSync: false + { + std::vector remoteDeviceList = { "remote_device_1" }; + EXPECT_CALL(*devMgrAdapterMock, GetUuidByNetworkId(_)).WillRepeatedly(Return("mock_uuid")); + EXPECT_CALL(*devMgrAdapterMock, ToUUID(testing::A &>())) + .WillOnce(Return(std::vector{ "mock_uuid_1" })); + EXPECT_CALL(*metaDataManagerMock, LoadMeta(_, _, _)) + .WillOnce(testing::Return(true)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*deviceMatrixMock, GetRemoteMask(_, _)).WillOnce(Return(std::make_pair(true, 0))); + EXPECT_CALL(*deviceMatrixMock, GetMask(_, _)).WillOnce(Return(std::make_pair(true, 0))); + auto result = manager->SyncOnStore(prefix, remoteDeviceList, func); + EXPECT_EQ(result, E_DB_ERROR); + } +} +}; // namespace DistributedDataTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/object_manager_test.cpp b/services/distributeddataservice/service/test/object_manager_test.cpp index e68fbf26231f77019030f7ad1e71315e6b6c1838..3462063ebd24bae59f3222302bc7d2001b1ae15a 100644 --- a/services/distributeddataservice/service/test/object_manager_test.cpp +++ b/services/distributeddataservice/service/test/object_manager_test.cpp @@ -444,6 +444,8 @@ HWTEST_F(ObjectManagerTest, Open001, TestSize.Level0) manager->delegate_ = manager->OpenObjectKvStore(); result = manager->Open(); ASSERT_EQ(result, DistributedObject::OBJECT_SUCCESS); + manager->ForceClose(); + ASSERT_EQ(manager->delegate_, nullptr); } /** @@ -529,35 +531,6 @@ HWTEST_F(ObjectManagerTest, Close001, TestSize.Level0) ASSERT_EQ(manager->syncCount_, 0); // 0 is for testing } -/** -* @tc.name: SyncOnStore001 -* @tc.desc: SyncOnStore test. -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(ObjectManagerTest, SyncOnStore001, TestSize.Level0) -{ - auto manager = ObjectStoreManager::GetInstance(); - manager->delegate_ = manager->OpenObjectKvStore(); - std::function &results)> func; - func = [](const std::map &results) { - return results; - }; - std::string prefix = "ObjectManagerTest"; - std::vector deviceList; - // not local device & syncDevices empty - deviceList.push_back("local1"); - EXPECT_CALL(*devMgrAdapterMock, IsSameAccount(_)).WillOnce(Return(true)); - auto result = manager->SyncOnStore(prefix, deviceList, func); - ASSERT_NE(result, OBJECT_SUCCESS); - // local device - deviceList.push_back("local"); - EXPECT_CALL(*devMgrAdapterMock, IsSameAccount(_)).WillOnce(Return(true)); - result = manager->SyncOnStore(prefix, deviceList, func); - ASSERT_EQ(result, OBJECT_SUCCESS); -} - /** * @tc.name: RetrieveFromStore001 * @tc.desc: RetrieveFromStore test. @@ -873,7 +846,7 @@ HWTEST_F(ObjectManagerTest, RegisterAssetsLister001, TestSize.Level0) auto result = manager->RegisterAssetsLister(); ASSERT_EQ(result, true); manager->objectAssetsSendListener_ = new ObjectAssetsSendListener(); - manager->objectAssetsRecvListener_ = new ObjectAssetsRecvListener();; + manager->objectAssetsRecvListener_ = new ObjectAssetsRecvListener(); result = manager->RegisterAssetsLister(); ASSERT_EQ(result, true); } diff --git a/services/distributeddataservice/service/test/object_service_impl_test.cpp b/services/distributeddataservice/service/test/object_service_impl_test.cpp index 11a66c41ffba0c9b9b6e9862af557d8cca824229..d433822afff2c5f1649313da251e655642d35468 100644 --- a/services/distributeddataservice/service/test/object_service_impl_test.cpp +++ b/services/distributeddataservice/service/test/object_service_impl_test.cpp @@ -20,11 +20,14 @@ #include #include "accesstoken_kit.h" +#include "device_manager_adapter_mock.h" #include "ipc_skeleton.h" #include "token_setproc.h" using namespace testing::ext; using namespace OHOS::DistributedObject; +using namespace std; +using namespace testing; namespace OHOS::Test { class ObjectServiceImplTest : public testing::Test { public: @@ -45,6 +48,7 @@ protected: ObjectStore::AssetBindInfo assetBindInfo_; pid_t pid_ = 10; uint32_t tokenId_ = 100; + static inline std::shared_ptr devMgrAdapterMock = nullptr; }; void ObjectServiceImplTest::SetUp() @@ -73,9 +77,14 @@ void ObjectServiceImplTest::SetUp() .assetName = "asset1.jpg", }; assetBindInfo_ = AssetBindInfo; + devMgrAdapterMock = make_shared(); + BDeviceManagerAdapter::deviceManagerAdapter = devMgrAdapterMock; } -void ObjectServiceImplTest::TearDown() {} +void ObjectServiceImplTest::TearDown() +{ + devMgrAdapterMock = nullptr; +} /** * @tc.name: OnAssetChanged001 @@ -152,6 +161,22 @@ HWTEST_F(ObjectServiceImplTest, ResolveAutoLaunch001, TestSize.Level1) EXPECT_EQ(ret, OBJECT_SUCCESS); } +/** + * @tc.name: OnInitialize001 + * @tc.desc: OnInitialize test. + * @tc.type: FUNC + */ +HWTEST_F(ObjectServiceImplTest, OnInitialize001, TestSize.Level1) +{ + std::shared_ptr objectServiceImpl = std::make_shared(); + objectServiceImpl->executors_ = nullptr; + DeviceInfo devInfo = { .uuid = "123" }; + EXPECT_CALL(*devMgrAdapterMock, GetLocalDevice()) + .WillOnce(Return(devInfo)); + int32_t ret = objectServiceImpl->OnInitialize(); + EXPECT_EQ(ret, OBJECT_INNER_ERROR); +} + /** * @tc.name: RegisterProgressObserver001 * @tc.desc: RegisterProgressObserver test.