diff --git a/services/backup_sa/include/module_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index 8bb77e1ad7bc90d84418f36f7841c4515fb328e1..63c01fb31982c27ef1502eaf56f8f11967881db8 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -720,6 +720,9 @@ private: const vector &bundleNames, std::string &oldBackupVersion); void AppStatReportErr(const string &bundleName, const string &func, RadarError err); void SaStatReport(const string &bundleName, const string &func, RadarError err); + void ClearIncrementalStatFile(int32_t userId, const string &bundleName); + BJsonCachedEntity CreateJsonEntity(UniqueFd &fd, + vector &bundleInfos, const std::vector &bundleNames); void TotalStart() { if (totalStatistic_ != nullptr) { @@ -760,6 +763,7 @@ private: static inline std::atomic seed {1}; std::atomic isConnectDied_ {false}; std::atomic isOccupyingSession_ {false}; + std::atomic isCreatingIncreaseFile_ {0}; sptr session_; sptr sched_; diff --git a/services/backup_sa/src/module_external/bms_adapter.cpp b/services/backup_sa/src/module_external/bms_adapter.cpp index 67eb26936874a63f3bcb85a9cb25232c3f2516de..5173a25c5eb65f9405da9ec3b0f99e961fcae7c2 100644 --- a/services/backup_sa/src/module_external/bms_adapter.cpp +++ b/services/backup_sa/src/module_external/bms_adapter.cpp @@ -205,7 +205,6 @@ static bool CreateIPCInteractionFiles(int32_t userId, const string &bundleName, backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR; } - HILOGI("bundleInteraction dir is:%{public}s", backupSaBundleDir.c_str()); if (access(backupSaBundleDir.data(), F_OK) != 0) { int32_t err = mkdir(backupSaBundleDir.data(), S_IRWXU | S_IRWXG); if (err != 0 && errno != EEXIST) { diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp index f223767e35240d2dd2691513a46b27ae02a8a8e4..60a1838e32c8f0e3a2319a69db5ac3dee24f0f7c 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -62,6 +62,7 @@ const std::string FILE_BACKUP_EVENTS = "FILE_BACKUP_EVENTS"; namespace { constexpr int32_t INDEX = 3; constexpr int32_t MS_1000 = 1000; +constexpr int32_t INCREMENTAL_COUNT = 1; const static string UNICAST_TYPE = "unicast"; } // namespace @@ -130,24 +131,47 @@ ErrCode Service::GetLocalCapabilitiesIncremental(const std::vector Service::CreateJsonEntity(UniqueFd &fd, + vector& bundleInfos, const std::vector &bundleNames) +{ + BJsonCachedEntity cachedEntity(move(fd)); + auto cache = cachedEntity.Structuralize(); + std::string backupVersion = BJsonUtil::ParseBackupVersion(); + cache.SetBackupVersion(backupVersion); + cache.SetSystemFullName(GetOSFullName()); + cache.SetDeviceType(GetDeviceType()); + bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(GetUserIdDefault(), bundleNames); + cache.SetBundleInfos(bundleInfos, true); + cachedEntity.Persist(); + HILOGI("Service GetLocalCapabilitiesIncremental persist, bundleInfos size:%{public}zu", bundleInfos.size()); + isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT); + if (isCreatingIncreaseFile_.load() <= 0) { + isCreatingIncreaseFile_.store(0); + const int userId = GetUserIdDefault(); + for (const auto &bundleInfo : bundleInfos) { + ClearIncrementalStatFile(userId, bundleInfo.name); + } + HILOGI("do ClearIncrementalStatFile finished"); + } + return cachedEntity; +} + UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector &bundleNames) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); try { - /* - Only called by restore app before InitBackupSession, - so there must be set init userId. - */ HILOGI("Begin"); if (session_ == nullptr || isOccupyingSession_.load()) { HILOGE("Get LocalCapabilities Incremental Error, session is empty or cleaning up the service"); return UniqueFd(-ENOENT); } session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); + isCreatingIncreaseFile_.fetch_add(INCREMENTAL_COUNT); ErrCode errCode = VerifyCaller(); if (errCode != ERR_OK) { HILOGE("Get local abilities info failed, Verify caller failed, errCode:%{public}d", errCode); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); + isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT); return UniqueFd(-ENOENT); } string path = BConstants::GetSaBundleBackupRootDir(GetUserIdDefault()); @@ -157,26 +181,20 @@ UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vectorDecreaseSessionCnt(__PRETTY_FUNCTION__); + isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT); return UniqueFd(-ENOENT); } - BJsonCachedEntity cachedEntity(move(fd)); - auto cache = cachedEntity.Structuralize(); - std::string backupVersion = BJsonUtil::ParseBackupVersion(); - cache.SetBackupVersion(backupVersion); - cache.SetSystemFullName(GetOSFullName()); - cache.SetDeviceType(GetDeviceType()); - auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(GetUserIdDefault(), bundleNames); - cache.SetBundleInfos(bundleInfos, true); - cachedEntity.Persist(); - HILOGI("Service GetLocalCapabilitiesIncremental persist"); + vector bundleInfos; + BJsonCachedEntity cachedEntity = CreateJsonEntity(fd, bundleInfos, bundleNames); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); - HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size()); return move(cachedEntity.GetFd()); } catch (const BError &e) { + isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); HILOGE("GetLocalCapabilitiesIncremental failed, errCode = %{public}d", e.GetCode()); return UniqueFd(-e.GetCode()); } catch (...) { + isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT); HILOGE("Unexpected exception"); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return UniqueFd(-EPERM); @@ -712,6 +730,7 @@ ErrCode Service::AppIncrementalDone(ErrCode errCode) } HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d", callerName.c_str(), errCode); + ClearIncrementalStatFile(GetUserIdDefault(), callerName); if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) { std::shared_ptr mutexPtr = GetExtensionMutex(callerName); if (mutexPtr == nullptr) { @@ -1119,4 +1138,29 @@ ErrCode Service::Cancel(const std::string& bundleName, int32_t &result) } return BError(BError::Codes::OK); } + +void Service::ClearIncrementalStatFile(int32_t userId, const string &bundleName) +{ + BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName); + string backupSaBundleDir; + if (bundleDetail.bundleIndex > 0) { + const std::string bundleNameIndex = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" + + bundleDetail.bundleName; + backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + + bundleNameIndex + BConstants::FILE_SEPARATOR_CHAR; + } else { + backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + + bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR; + } + if (access(backupSaBundleDir.c_str(), F_OK) != ERR_OK) { + HILOGD("ClearIncrementalStatFile, access dir failed errno = %{public}d", errno); + return; + } + if (!ForceRemoveDirectoryBMS(backupSaBundleDir.c_str())) { + HILOGE("Failed to delete SaBundleBackupDir cache: %{public}s", + backupSaBundleDir.c_str()); + return; + } +} + } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/sub_service.cpp b/services/backup_sa/src/module_ipc/sub_service.cpp index 7c83fd08f98e657d274e451d35012217fcf85103..94254c6fdc26206b1eb97b19f84c0edfbfe063c6 100644 --- a/services/backup_sa/src/module_ipc/sub_service.cpp +++ b/services/backup_sa/src/module_ipc/sub_service.cpp @@ -1100,7 +1100,6 @@ ErrCode Service::GetBackupDataSize(bool isPreciseScan, const std::vectorDecreaseSessionCnt(__PRETTY_FUNCTION__); return BError(BError::Codes::SA_INVAL_ARG, "verify caller failed"); } - BundleMgrAdapter::CreatBackupEnv(bundleNameList, GetUserIdDefault()); CyclicSendScannedInfo(isPreciseScan, bundleNameList); return BError(BError::Codes::OK); } catch (...) { diff --git a/tests/mock/direct_ex_mock/direct_ex_mock.cpp b/tests/mock/direct_ex_mock/direct_ex_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e2fe36e54abce0b79f42fdc5fa8ce2588f586d5 --- /dev/null +++ b/tests/mock/direct_ex_mock/direct_ex_mock.cpp @@ -0,0 +1,21 @@ +/* +* 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 "direct_ex_mock.h" + +bool OHOS::ForceRemoveDirectoryBMS(const std::string& path) +{ + return AppFileService::DirectoryFuncMock::directoryFunc_->ForceRemoveDirectoryBMS(path); +} \ No newline at end of file diff --git a/tests/mock/direct_ex_mock/direct_ex_mock.h b/tests/mock/direct_ex_mock/direct_ex_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..5ab781775d7d70df4ddee3a5e4c7ccb3f96ab51a --- /dev/null +++ b/tests/mock/direct_ex_mock/direct_ex_mock.h @@ -0,0 +1,42 @@ +/* +* 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 FILEMANAGEMENT_APP_FILE_SERVICE_DIRECT_EX_MOCK_H +#define FILEMANAGEMENT_APP_FILE_SERVICE_DIRECT_EX_MOCK_H + +#include + +#include + +#include "directory_ex.h" + +namespace OHOS { +namespace AppFileService { +class DirectoryFunc { +public: + virtual ~DirectoryFunc() = default; + virtual bool ForceRemoveDirectoryBMS(const std::string&) = 0; +public: + static inline std::shared_ptr directoryFunc_ = nullptr; +}; + +class DirectoryFuncMock : public DirectoryFunc { +public: + MOCK_METHOD(bool, ForceRemoveDirectoryBMS, (const std::string&)); +}; +} // namespace AppFileService +} // namespace OHOS + +#endif // FILEMANAGEMENT_APP_FILE_SERVICE_LIBRARY_FUNC_MOCK_H \ No newline at end of file diff --git a/tests/unittests/backup_sa/module_ipc/BUILD.gn b/tests/unittests/backup_sa/module_ipc/BUILD.gn index 3c8a43658c1d1cd7a7df72676949584e1cc23588..74a142bed8edd9b5250f789a8c66d2701498069e 100644 --- a/tests/unittests/backup_sa/module_ipc/BUILD.gn +++ b/tests/unittests/backup_sa/module_ipc/BUILD.gn @@ -448,6 +448,7 @@ ohos_unittest("backup_service_incremental_test") { "${path_backup_mock}/module_sched/sched_scheduler_mock.cpp", "${path_backup_mock}/utils_mock/src/b_jsonutil_mock.cpp", "${path_backup_mock}/utils_mock/src/backup_para_mock.cpp", + "${path_backup_mock}/direct_ex_mock/direct_ex_mock.cpp", "${path_backup}/frameworks/native/backup_kit_inner/src/service_client.cpp", "service_incremental_test.cpp", ] @@ -464,6 +465,7 @@ ohos_unittest("backup_service_incremental_test") { "${path_backup_mock}/module_external/include", "${path_backup_mock}/module_ipc/include", "${path_backup_mock}/utils_mock/include", + "${path_backup_mock}/direct_ex_mock", ] deps = [ diff --git a/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp b/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp index ce96dcb764c52d78ff1b2cc79340eb7645bd1743..9111b9b552c389d8890f6eeb0121f41f4621048a 100644 --- a/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp +++ b/tests/unittests/backup_sa/module_ipc/service_incremental_test.cpp @@ -19,6 +19,7 @@ #include "bms_adapter_mock.h" #include "b_json/b_json_entity_caps.h" #include "b_jsonutil_mock.h" +#include "direct_ex_mock.h" #include "ipc_skeleton_mock.h" #include "sa_backup_connection_mock.h" #include "service_reverse_proxy_mock.h" @@ -30,6 +31,7 @@ namespace OHOS::FileManagement::Backup { using namespace std; +using namespace OHOS::AppFileService; class BService { public: @@ -513,6 +515,7 @@ public: static inline shared_ptr skeleton = nullptr; static inline sptr srProxy = nullptr; static inline shared_ptr srvMock = nullptr; + static inline shared_ptr directMock = nullptr; }; void ServiceIncrementalTest::SetUpTestCase(void) @@ -537,6 +540,8 @@ void ServiceIncrementalTest::SetUpTestCase(void) skeleton = make_shared(); IPCSkeletonMock::skeleton = skeleton; srProxy = sptr(new ServiceReverseProxyMock()); + directMock = make_shared(); + DirectoryFuncMock::directoryFunc_ = directMock; } void ServiceIncrementalTest::TearDownTestCase() @@ -561,6 +566,8 @@ void ServiceIncrementalTest::TearDownTestCase() srProxy = nullptr; ServiceMock::serviceMock = nullptr; srvMock = nullptr; + DirectoryFuncMock::directoryFunc_ = nullptr; + directMock = nullptr; } /** @@ -592,12 +599,28 @@ HWTEST_F(ServiceIncrementalTest, SUB_ServiceIncremental_GetLocalCapabilitiesIncr fd = service->GetLocalCapabilitiesIncremental({}); EXPECT_EQ(static_cast(fd), -ENOENT); - vector info; + vector infos; + infos.emplace_back(BJsonEntityCaps::BundleInfo{.name = "bundleName", .appIndex = 0}); + EXPECT_CALL(*directMock, ForceRemoveDirectoryBMS(_)).WillRepeatedly(Return(true)); EXPECT_CALL(*srvMock, VerifyCaller()).WillOnce(Return(BError(BError::Codes::OK).GetCode())); - EXPECT_CALL(*srvMock, GetUserIdDefault()).WillOnce(Return(0)).WillOnce(Return(0)); + EXPECT_CALL(*srvMock, GetUserIdDefault()).WillOnce(Return(0)).WillOnce(Return(0)).WillOnce(Return(0)); EXPECT_CALL(*bms, GetBundleInfosForIncremental(An(), An&>())) - .WillOnce(Return(info)); + .WillOnce(Return(infos)); + + BJsonUtil::BundleDetailInfo bundleInfo; + bundleInfo.bundleIndex = 1; + bundleInfo.bundleName = "bundleName"; + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); fd = service->GetLocalCapabilitiesIncremental({}); + + EXPECT_CALL(*srvMock, VerifyCaller()).WillOnce(Return(BError(BError::Codes::OK).GetCode())); + EXPECT_CALL(*srvMock, GetUserIdDefault()).WillOnce(Return(0)).WillOnce(Return(0)).WillOnce(Return(0)); + EXPECT_CALL(*bms, GetBundleInfosForIncremental(An(), An&>())) + .WillOnce(Return(infos)); + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); + service->isCreatingIncreaseFile_.store(2); + fd = service->GetLocalCapabilitiesIncremental({}); + service->isCreatingIncreaseFile_.store(0); EXPECT_TRUE(static_cast(fd) > 0); } catch (...) { EXPECT_TRUE(false); @@ -1342,28 +1365,37 @@ HWTEST_F(ServiceIncrementalTest, SUB_ServiceIncremental_AppIncrementalDone_0000, int32_t errCode = BError(BError::Codes::OK).GetCode(); auto session_ = service->session_; service->session_ = nullptr; + EXPECT_CALL(*srvMock, GetUserIdDefault()).WillRepeatedly(Return(100)); + BJsonUtil::BundleDetailInfo bundleInfo; + bundleInfo.bundleIndex = 0; + bundleInfo.bundleName = "bundleName"; + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); auto ret = service->AppIncrementalDone(errCode); EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); service->session_ = session_; EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)) .WillOnce(Return(BError(BError::Codes::SA_INVAL_ARG).GetCode())); + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); ret = service->AppIncrementalDone(errCode); EXPECT_EQ(ret, BError(BError::Codes::SA_INVAL_ARG).GetCode()); EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(false)); + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); ret = service->AppIncrementalDone(errCode); EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); service->backupExtMutexMap_.clear(); EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(false)); + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); ret = service->AppIncrementalDone(BError(BError::Codes::SA_INVAL_ARG).GetCode()); EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); EXPECT_CALL(*srvMock, VerifyCallerAndGetCallerName(_)).WillOnce(Return(BError(BError::Codes::OK).GetCode())); EXPECT_CALL(*session, OnBundleFileReady(_, _)).WillOnce(Return(true)); + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); ret = service->AppIncrementalDone(errCode); EXPECT_EQ(ret, BError(BError::Codes::OK).GetCode()); } catch (...) { @@ -2096,4 +2128,78 @@ HWTEST_F(ServiceIncrementalTest, SUB_ServiceIncremental_RemoveExtensionMutex_000 } GTEST_LOG_(INFO) << "ServiceIncrementalTest-end SUB_ServiceIncremental_RemoveExtensionMutex_0000"; } + +/** + * @tc.number: SUB_ServiceIncremental_ClearIncrementalStatFile_0000 + * @tc.name: SUB_ServiceIncremental_ClearIncrementalStatFile_0000 + * @tc.desc: 测试 ClearIncrementalStatFile 分身与一般应用分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issueIAKC3I + */ +HWTEST_F(ServiceIncrementalTest, SUB_ServiceIncremental_ClearIncrementalStatFile_0000, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceIncrementalTest-begin SUB_ServiceIncremental_ClearIncrementalStatFile_0000"; + try { + + int userId = BConstants::DEFAULT_USER_ID; + ASSERT_TRUE(service != nullptr); + BJsonUtil::BundleDetailInfo bundleInfo; + bundleInfo.bundleIndex = 1; + bundleInfo.bundleName = "com.example.app2backup"; + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); + service->ClearIncrementalStatFile(userId, bundleInfo.bundleName); + + bundleInfo.bundleIndex = 0; + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); + service->ClearIncrementalStatFile(userId, bundleInfo.bundleName); + EXPECT_EQ(bundleInfo.bundleIndex, 0); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceIncrementalTest-an exception occurred by ClearIncrementalStatFile."; + } + GTEST_LOG_(INFO) << "ServiceIncrementalTest-end SUB_ServiceIncremental_ClearIncrementalStatFile_0000"; +} + +/** + * @tc.number: SUB_ServiceIncremental_ClearIncrementalStatFile_0100 + * @tc.name: SUB_ServiceIncremental_ClearIncrementalStatFile_0100 + * @tc.desc: 测试 ClearIncrementalStatFile 的文件删除异常分支 + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: issueIAKC3I + */ +HWTEST_F(ServiceIncrementalTest, SUB_ServiceIncremental_ClearIncrementalStatFile_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ServiceIncrementalTest-begin SUB_ServiceIncremental_ClearIncrementalStatFile_0100"; + try { + + int userId = BConstants::DEFAULT_USER_ID; + ASSERT_TRUE(service != nullptr); + BJsonUtil::BundleDetailInfo bundleInfo; + bundleInfo.bundleIndex = 0; + bundleInfo.bundleName = "com.example.app2backup"; + string path = BConstants::GetSaBundleBackupRootDir(userId).data() + bundleInfo.bundleName; + string cmdMkdir = string("mkdir -p ") + path; + int ret = system(cmdMkdir.c_str()); + EXPECT_EQ(ret, 0); + + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); + service->ClearIncrementalStatFile(userId, bundleInfo.bundleName); + + EXPECT_CALL(*directMock, ForceRemoveDirectoryBMS(_)).WillOnce(Return(false)); + EXPECT_CALL(*jsonUtil, ParseBundleNameIndexStr(_)).WillOnce(Return(bundleInfo)); + service->ClearIncrementalStatFile(userId, bundleInfo.bundleName); + EXPECT_EQ(bundleInfo.bundleIndex, 0); + string cmdRmdir = string("rm -r ") + path; + ret = system(cmdRmdir.c_str()); + EXPECT_EQ(ret, 0); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ServiceIncrementalTest-an exception occurred by ClearIncrementalStatFile."; + } + GTEST_LOG_(INFO) << "ServiceIncrementalTest-end SUB_ServiceIncremental_ClearIncrementalStatFile_0100"; +} } \ No newline at end of file