diff --git a/services/distributeddataservice/service/cloud/sync_manager.cpp b/services/distributeddataservice/service/cloud/sync_manager.cpp index 773fca44bac834540d494dc7bf73daf23538d448..63fd4459c8527da33c1b921f60b5205c89a95da1 100644 --- a/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -638,10 +638,8 @@ std::pair SyncManager::GetStore(const StoreMetaData & return { E_NOT_SUPPORT, nullptr }; } auto [status, store] = AutoCache::GetInstance().GetDBStore(meta, {}); - if (status == E_SCREEN_LOCKED) { - return { E_SCREEN_LOCKED, nullptr }; - } else if (store == nullptr) { - return { E_ERROR, nullptr }; + if (status != E_OK || store == nullptr) { + return { status, nullptr }; } CloudInfo info; info.user = user; diff --git a/services/distributeddataservice/service/cloud/sync_manager.h b/services/distributeddataservice/service/cloud/sync_manager.h index a24f0ae6649a07bb18c8ec6dd8ea8882972cc0be..a8399ceddda21a6e21ad67d582e885ade511442d 100644 --- a/services/distributeddataservice/service/cloud/sync_manager.h +++ b/services/distributeddataservice/service/cloud/sync_manager.h @@ -19,9 +19,9 @@ #include "cloud/cloud_event.h" #include "cloud/cloud_info.h" #include "cloud/cloud_last_sync_info.h" +#include "cloud/sync_event.h" #include "cloud/sync_strategy.h" #include "cloud_types.h" -#include "cloud/sync_event.h" #include "concurrent_map.h" #include "dfx/radar_reporter.h" #include "eventcenter/event.h" @@ -72,7 +72,6 @@ public: void SetError(int32_t code) const; void SetCompensation(bool isCompensation); void SetTriggerMode(int32_t triggerMode); - void SetPrepareTraceId(const std::string &prepareTraceId); std::shared_ptr GenerateQuery(const std::string &store, const Tables &tables); bool Contains(const std::string &storeName); inline static constexpr const char *DEFAULT_ID = "default"; diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index c93995cf0af77e6ac9cfb5639ee6990255496243..9310059911ccec4878c76fa618c827458f937c9d 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -166,6 +166,56 @@ ohos_unittest("CloudDataMockTest") { ] } +ohos_unittest("SyncManagerTest") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "${datamgr_service_path}/cfi_blocklist.txt" + } + module_out_path = module_output_path + sources = [ + #"${data_service_path}/service/cloud/sync_manager.cpp", + #"${data_service_path}/service/cloud/sync_strategies/network_sync_strategy.cpp", + #"${data_service_path}/service/test/mock/checker_mock.cpp", + #"mock/account_delegate_mock.cpp", + "sync_manager_test.cpp", + ] + + configs = [ ":module_private_config" ] + + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + + deps = [ + "${data_service_path}/adapter/account:distributeddata_account", + "${data_service_path}/adapter/communicator:distributeddata_communicator", + "${data_service_path}/adapter/dfx:distributeddata_dfx", + "${data_service_path}/adapter/schema_helper:distributeddata_schema_helper", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service/bootstrap:distributeddata_bootstrap", + "${data_service_path}/service/common:distributeddata_common", + "${data_service_path}/service/rdb:distributeddata_rdb", + "mock:distributeddata_mock_static", + ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "device_manager:devicemanagersdk", + "googletest:gmock", + "googletest:gtest", + "hicollie:libhicollie", + "hilog:libhilog", + "ipc:ipc_single", + "json:nlohmann_json_static", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] +} + ohos_unittest("CloudServiceImplTest") { sanitize = { @@ -2485,6 +2535,7 @@ group("unittest") { ":CloudDataMockTest", ":CloudServiceImplTest", ":CloudTest", + ":SyncManagerTest", "ohos_test:copy_ohos_test", "testCloud:testCloud", ] diff --git a/services/distributeddataservice/service/test/sync_manager_test.cpp b/services/distributeddataservice/service/test/sync_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3effc46eb36174cfd0254c4992a9ce27a149eb58 --- /dev/null +++ b/services/distributeddataservice/service/test/sync_manager_test.cpp @@ -0,0 +1,277 @@ +/* +* 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 "SyncManagerTest" + +#include "sync_manager.h" + +#include +#include + +#include "cloud/cloud_server.h" +#include "cloud_service_impl.h" +#include "communicator/device_manager_adapter.h" +#include "device_matrix.h" +#include "eventcenter/event_center.h" +#include "ipc_skeleton.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "mock/account_delegate_mock.h" +#include "mock/db_store_mock.h" +#include "network_delegate_mock.h" + +using namespace testing::ext; +using namespace testing; +using namespace DistributedDB; +using namespace OHOS::DistributedData; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; + +namespace OHOS::Test { +namespace DistributedDataTest { +static constexpr const char *TEST_CLOUD_BUNDLE = "test_cloud_bundleName"; +static constexpr const char *TEST_CLOUD_APPID = "test_cloud_appid"; +static constexpr const char *TEST_CLOUD_STORE = "test_cloud_store"; +static constexpr const char *TEST_CLOUD_ID = "test_cloud_id"; +static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_1 = "test_cloud_database_alias_1"; +static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_2 = "test_cloud_database_alias_2"; +static constexpr const char *TEST_CLOUD_PATH = "/data/app/el2/100/database/test_cloud_bundleName/entry/rdb/" + "test_cloud_store"; + +class MockEventCenter : public EventCenter { +public: + MOCK_METHOD(void, PostEvent, (std::unique_ptr event), (override)); + MOCK_METHOD(void, Subscribe, (int32_t eventId, std::function handler), (override)); +}; + +class MockGeneralStore : public GeneralStore { +public: + MOCK_METHOD(std::pair, LockCloudDB, (), (override)); + MOCK_METHOD(int32_t, UnLockCloudDB, (), (override)); +}; + +class SyncManagerTest : public testing::Test { +protected: + void SetUp() override + { + // 替换全局 EventCenter 实例 + originalEventCenter_ = &EventCenter::GetInstance(); + mockEventCenter_ = std::make_unique(); + EventCenter::SetInstance(mockEventCenter_.get()); + + // 初始化 SyncManager 并订阅事件 + syncManager_ = std::make_unique(); + + // 初始化 RdbServiceImpl + rdbService_ = std::make_unique(); + + // Mock 其他依赖 + mockMetaDataManager_ = std::make_shared(); + mockCloudServer_ = std::make_shared(); + MetaDataManager::SetInstance(mockMetaDataManager_); + CloudServer::SetInstance(mockCloudServer_); + } + + void TearDown() override + { + EventCenter::SetInstance(originalEventCenter_); + MetaDataManager::SetInstance(nullptr); + CloudServer::SetInstance(nullptr); + } + + std::unique_ptr syncManager_; + std::unique_ptr rdbService_; + std::unique_ptr mockEventCenter_; + std::shared_ptr mockMetaDataManager_; + std::shared_ptr mockCloudServer_; + +private: + EventCenter *originalEventCenter_; +}; + +/** + * @tc.name: SyncManager_LockCloudContainer_Integration + * @tc.desc: Test complete lock cloud container flow through PostEvent + * @tc.type: FUNC + * @tc.author: Hollokin + */ +TEST_F(SyncManagerTest, LockCloudContainer_Integration) +{ + // 1. 准备测试数据 + RdbSyncerParam param; + param.bundleName_ = "com.example.test"; + param.storeName_ = "testStore"; + + StoreInfo storeInfo{ 100, param.bundleName_, param.storeName_, "instance1" }; + StoreMetaMapping metaMapping; + metaMapping.bundleName = param.bundleName_; + metaMapping.storeId = param.storeName_; + metaMapping.cloudPath = "/cloud/path"; + + // 2.2 设置元数据加载预期 + EXPECT_CALL(*mockMetaDataManager_, LoadMeta(_, _, _)).WillOnce(DoAll(SetArgReferee<1>(metaMapping), Return(true))); + + // 2.3 设置数据库操作预期 + auto mockStore = std::make_shared(); + EXPECT_CALL(*mockStore, LockCloudDB()).WillOnce(Return(std::make_pair(0, 3600))); + EXPECT_CALL(*mockCloudServer_, ConnectCloudDB(_, _, _)).WillOnce(Return(mockStore)); + + // 3. 初始化 SyncManager (触发订阅) + syncManager_ = std::make_unique(); + auto evt = std::make_unique(CloudEvent::LOCK_CLOUD_CONTAINER, std::move(storeInfo), nullptr); + EventCenter::GetInstance().PostEvent(std::move(evt)); + + std::pair result{ E_ERROR, 10000 }; + CloudLockEvent::Callback callback = [&result](int32_t status, uint32_t expiredTime) { + ZLOGI("tyx::SyncManagerTest LockCloudContainer_Integration callback, status:%{public}d, " + "expiredTime:%{public}u", status, expiredTime); + result.first = 0; + result.second = 3600; + }; + evt = std::make_unique(CloudEvent::LOCK_CLOUD_CONTAINER, std::move(storeInfo), callback); + EventCenter::GetInstance().PostEvent(std::move(evt)); + ZLOGI("tyx::SyncManagerTest LockCloudContainer_Integration start to LockCloudContainer"); + // 4. 调用 RdbServiceImpl 接口 + auto [status, expiredTime] = rdbService_->LockCloudContainer(param); + ZLOGI("tyx::SyncManagerTest LockCloudContainer_Integration LockCloudContainer end."); + + // 6. 验证结果 + EXPECT_EQ(result.first, 0); + EXPECT_EQ(result.second, 3600); +} + +#if 0 +/** + * @tc.name: SyncManager_UnlockCloudContainer_Integration + * @tc.desc: Test complete unlock cloud container flow through PostEvent + * @tc.type: FUNC + * @tc.require: AR000H0F5R + */ +TEST_F(SyncManagerTest, UnlockCloudContainer_Integration) +{ + // 1. 准备测试数据 + RdbSyncerParam param; + param.bundleName_ = "com.example.test"; + param.storeName_ = "testStore"; + + StoreInfo storeInfo{ 100, param.bundleName_, param.storeName_, "instance1" }; + StoreMetaMapping metaMapping; + metaMapping.bundleName = param.bundleName_; + metaMapping.storeId = param.storeName_; + metaMapping.cloudPath = "/cloud/path"; + + // 2. 设置 Mock 预期 + // 2.1 设置 EventCenter 订阅预期 + EXPECT_CALL(*mockEventCenter_, Subscribe(CloudEvent::UNLOCK_CLOUD_CONTAINER, _)) + .WillOnce([this](int32_t, auto handler) { + // 保存 handler 供后续测试使用 + this->unlockHandler_ = handler; + }); + + // 2.2 设置元数据加载预期 + EXPECT_CALL(*mockMetaDataManager_, LoadMeta(_, _, _)).WillOnce(DoAll(SetArgReferee<1>(metaMapping), Return(true))); + + // 2.3 设置数据库操作预期 + auto mockStore = std::make_shared(); + EXPECT_CALL(*mockStore, UnLockCloudDB()).WillOnce(Return(0)); + EXPECT_CALL(*mockCloudServer_, ConnectCloudDB(_, _, _)).WillOnce(Return(mockStore)); + + // 3. 初始化 SyncManager (触发订阅) + syncManager_ = std::make_unique(); + + // 4. 调用 RdbServiceImpl 接口 (假设有对应的解锁接口) + int32_t status = -1; + CloudLockEvent event(CloudEvent::UNLOCK_CLOUD_CONTAINER, storeInfo, [&status](int32_t s, uint32_t) { + status = s; + }); + EventCenter::GetInstance().PostEvent(std::make_unique(event)); + + // 5. 模拟事件处理 + if (unlockHandler_) { + unlockHandler_(event); + } + + // 6. 验证结果 + EXPECT_EQ(status, 0); +} + +/** + * @tc.name: SyncManager_LockCloudContainer_PermissionDenied + * @tc.desc: Test lock container with permission denied + * @tc.type: FUNC + * @tc.require: AR000H0F5R + */ +TEST_F(SyncManagerTest, LockCloudContainer_PermissionDenied) +{ + // 1. 准备测试数据 (无效参数) + RdbSyncerParam param; + param.bundleName_ = "com.example.unauthorized"; + param.storeName_ = "testStore"; + + // 2. 设置权限校验失败 + EXPECT_CALL(*mockAccessControl_, CheckAccess(param.bundleName_, param.storeName_)).WillOnce(Return(false)); + + // 3. 调用接口 + auto [status, expiredTime] = rdbService_->LockCloudContainer(param); + + // 4. 验证结果 + EXPECT_NE(status, 0); + EXPECT_EQ(expiredTime, 0); + + // 5. 确保没有事件被发布 + EXPECT_CALL(*mockEventCenter_, PostEvent(_)).Times(0); +} + +/** + * @tc.name: SyncManager_LockCloudContainer_MetaLoadFailed + * @tc.desc: Test lock container when meta data loading fails + * @tc.type: FUNC + * @tc.require: AR000H0F5R + */ +TEST_F(SyncManagerTest, LockCloudContainer_MetaLoadFailed) +{ + // 1. 准备测试数据 + RdbSyncerParam param; + param.bundleName_ = "com.example.test"; + param.storeName_ = "testStore"; + + StoreInfo storeInfo{ 100, param.bundleName_, param.storeName_, "instance1" }; + + // 2. 设置 Mock 预期 + // 2.1 设置元数据加载失败 + EXPECT_CALL(*mockMetaDataManager_, LoadMeta(_, _, _)).WillOnce(Return(false)); + + // 3. 初始化 SyncManager + syncManager_ = std::make_unique(); + + // 4. 调用接口 + auto [status, expiredTime] = rdbService_->LockCloudContainer(param); + + // 5. 模拟事件处理 + if (lockHandler_) { + bool callbackCalled = false; + CloudLockEvent event(CloudEvent::LOCK_CLOUD_CONTAINER, storeInfo, [&](int32_t s, uint32_t) { + callbackCalled = true; + status = s; + }); + lockHandler_(event); + EXPECT_TRUE(callbackCalled); + } + + // 6. 验证结果 + EXPECT_NE(status, 0); + EXPECT_EQ(expiredTime, 0); +} +#endif +} // namespace DistributedDataTest +} // namespace OHOS::Test \ No newline at end of file