diff --git a/interfaces/inner_api/native/cloud_file_kit_inner/cloud_asset_read_session.h b/interfaces/inner_api/native/cloud_file_kit_inner/cloud_asset_read_session.h index dc6e13b61e3b02455a5203d8a196e337809dfc68..b86f695741bc58cbcc401909b31766d7d7ac5767 100644 --- a/interfaces/inner_api/native/cloud_file_kit_inner/cloud_asset_read_session.h +++ b/interfaces/inner_api/native/cloud_file_kit_inner/cloud_asset_read_session.h @@ -17,6 +17,7 @@ #define OHOS_CLOUD_FILE_CLOUD_ASSET_READ_SESSION_H #include +#include #include #include "cloud_info.h" @@ -35,6 +36,7 @@ public: virtual void SentPrepareTraceId(std::string prepareTraceId); void SetPrepareTraceId(std::string prepareTraceId); std::string GetPrepareTraceId(); + int32_t sessionCount {0}; private: std::string traceId_; diff --git a/services/cloudfiledaemon/include/cloud_disk/cloud_disk_inode.h b/services/cloudfiledaemon/include/cloud_disk/cloud_disk_inode.h index dd18e84a2cbafc6b25a2950c421b09d18d3f818a..f037ebc509d1832a90fccf8f2950b6b8f0f22b37 100644 --- a/services/cloudfiledaemon/include/cloud_disk/cloud_disk_inode.h +++ b/services/cloudfiledaemon/include/cloud_disk/cloud_disk_inode.h @@ -79,7 +79,7 @@ struct CloudDiskInode { fuse_ino_t parent{0}; std::atomic refCount{0}; std::string path; // just used in local file operation - std::shared_mutex inodeLock; + std::shared_mutex sessionLock; /* ops means file operation that uses local or database */ std::shared_ptr ops{nullptr}; @@ -90,6 +90,7 @@ struct CloudDiskFuseData { int64_t bundleNameId{1}; int64_t fileId{0}; std::shared_ptr rootNode{nullptr}; + std::unordered_map> readSessionCache; std::unordered_map> inodeCache; std::unordered_map> fileCache; std::unordered_map localIdCache; diff --git a/services/cloudfiledaemon/include/cloud_disk/file_operations_cloud.h b/services/cloudfiledaemon/include/cloud_disk/file_operations_cloud.h index 6711676788883e7ab38647b8d1027c86369a815a..ad6d685774d09be975b6c5f1567a62cede4749aa 100644 --- a/services/cloudfiledaemon/include/cloud_disk/file_operations_cloud.h +++ b/services/cloudfiledaemon/include/cloud_disk/file_operations_cloud.h @@ -28,7 +28,19 @@ struct CloudOpenParams { std::shared_ptr metaFile; std::shared_ptr filePtr; }; - + +struct SessionCountParams { + std::string path; + std::string cloudId; + std::string assets; +}; + +struct HandleOpenErrorParams { + std::shared_ptr filePtr; + std::shared_ptr inoPtr; + fuse_ino_t ino; +}; + class FileOperationsCloud final : public FileOperationsBase { public: void Lookup(fuse_req_t req, fuse_ino_t parent, const char *name) override; diff --git a/services/cloudfiledaemon/src/cloud_disk/file_operations_cloud.cpp b/services/cloudfiledaemon/src/cloud_disk/file_operations_cloud.cpp index 824d6bae5b0b32f03986909ff40a58cc9ca69e1e..87b9bf17259ab91e4ed2bfc0a5f848330714b104 100644 --- a/services/cloudfiledaemon/src/cloud_disk/file_operations_cloud.cpp +++ b/services/cloudfiledaemon/src/cloud_disk/file_operations_cloud.cpp @@ -422,23 +422,20 @@ static int32_t HandleCloudOpenSuccess(struct fuse_file_info *fi, struct CloudDis if (metaBase.fileType != FILE_TYPE_CONTENT) { string path = CloudFileUtils::GetLocalFilePath(inoPtr->cloudId, inoPtr->bundleName, data->userId); string tmpPath = CloudFileUtils::GetLocalDKCachePath(inoPtr->cloudId, inoPtr->bundleName, data->userId); - { - std::unique_lock lck(inoPtr->inodeLock); - auto ret = CheckBucketPath(inoPtr->cloudId, inoPtr->bundleName, data->userId, tmpPath); - if (ret != EOK) { - LOGE("check bucketPath failed, ret = %{public}d", ret); - return ret; - } - if (access(path.c_str(), F_OK) != 0) { - ret = rename(tmpPath.c_str(), path.c_str()); - if (ret == EOK) { - DatabaseManager &databaseManager = DatabaseManager::GetInstance(); - auto rdbstore = databaseManager.GetRdbStore(inoPtr->bundleName, data->userId); - rdbstore->UpdateTHMStatus(metaFile, metaBase, CloudSync::DOWNLOADED_THM); - } else { - LOGE("path rename failed, tmpPath:%{public}s, errno:%{public}d", tmpPath.c_str(), errno); - return errno; - } + auto ret = CheckBucketPath(inoPtr->cloudId, inoPtr->bundleName, data->userId, tmpPath); + if (ret != EOK) { + LOGE("check bucketPath failed, ret = %{public}d", ret); + return ret; + } + if (access(path.c_str(), F_OK) != 0) { + ret = rename(tmpPath.c_str(), path.c_str()); + if (ret == EOK) { + DatabaseManager &databaseManager = DatabaseManager::GetInstance(); + auto rdbstore = databaseManager.GetRdbStore(inoPtr->bundleName, data->userId); + rdbstore->UpdateTHMStatus(metaFile, metaBase, CloudSync::DOWNLOADED_THM); + } else { + LOGE("path rename failed, tmpPath:%{public}s, errno:%{public}d", tmpPath.c_str(), errno); + return errno; } } unsigned int flags = GetFileOpenFlags(fi->flags); @@ -507,6 +504,30 @@ static int32_t DoCloudOpen(fuse_req_t req, struct fuse_file_info *fi, } } +static void ErasePathCache(string path, CloudDiskFuseData *data) +{ + if (data->readSessionCache.find(path) != data->readSessionCache.end()) { + data->readSessionCache.erase(path); + } +} + +static void SetSessionCount(struct CloudDiskFuseData *data, const struct SessionCountParams &sessionParam, + shared_ptr filePtr, shared_ptr database) +{ + string path = sessionParam.path; + if (data->readSessionCache.find(path) != data->readSessionCache.end()) { + data->readSessionCache[path]->sessionCount++; + filePtr->readSession = data->readSessionCache[path]; + return; + } + filePtr->readSession = database->NewAssetReadSession(data->userId, "file", + sessionParam.cloudId, sessionParam.assets, path); + if (filePtr->readSession) { + data->readSessionCache[path] = filePtr->readSession; + data->readSessionCache[path]->sessionCount++; + } +} + static int32_t GetNewSession(shared_ptr inoPtr, string &path, struct CloudDiskFuseData *data, shared_ptr database, CloudOpenParams cloudOpenParams) @@ -515,24 +536,65 @@ static int32_t GetNewSession(shared_ptr inoPtr, string assets = "content"; auto metaBase = cloudOpenParams.metaBase; auto filePtr = cloudOpenParams.filePtr; - if (metaBase.fileType == FILE_TYPE_THUMBNAIL) { - assets = "thumbnail"; - } - if (metaBase.fileType == FILE_TYPE_LCD) { - assets = "lcd"; - } - DatabaseManager &databaseManager = DatabaseManager::GetInstance(); - auto rdbStore = databaseManager.GetRdbStore(inoPtr->bundleName, data->userId); - int32_t ret = rdbStore->GetSrcCloudId(inoPtr->cloudId, cloudId); - if (ret) { - LOGE("get %{public}s cloudId failed", assets.c_str()); - return ret; + if (metaBase.fileType == FILE_TYPE_THUMBNAIL || + metaBase.fileType == FILE_TYPE_LCD) { + assets = (metaBase.fileType == FILE_TYPE_THUMBNAIL) ? "thumbnail" : "lcd"; + DatabaseManager &databaseManager = DatabaseManager::GetInstance(); + auto rdbStore = databaseManager.GetRdbStore(inoPtr->bundleName, data->userId); + auto ret = rdbStore->GetSrcCloudId(inoPtr->cloudId, cloudId); + if (ret) { + LOGE("get %{public}s cloudId failed", assets.c_str()); + return ret; + } } LOGD("cloudId %s", cloudId.c_str()); - filePtr->readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + struct SessionCountParams sessionParam = {path, cloudId, assets}; + SetSessionCount(data, sessionParam, filePtr, database); return EOK; } +static void HandleOpenFail(HandleOpenErrorParams params, string path, CloudDiskFuseData *data, + fuse_file_info *fi) +{ + ErasePathCache(path, data); + params.filePtr->readSession = nullptr; + FileOperationsHelper::PutCloudDiskFile(data, params.filePtr, fi->fh); + fuse_inval(data->se, params.inoPtr->parent, params.ino, params.inoPtr->fileName); +} + +static void HandleSessionNull(HandleOpenErrorParams params, CloudDiskFuseData *data, + fuse_file_info *fi) +{ + CLOUD_FILE_FAULT_REPORT(CloudFile::CloudFileFaultInfo{"", CloudFile::FaultOperation::OPEN, + CloudFile::FaultType::DRIVERKIT, EPERM, "readSession is null"}); + FileOperationsHelper::PutCloudDiskFile(data, params.filePtr, fi->fh); + fuse_inval(data->se, params.inoPtr->parent, params.ino, params.inoPtr->fileName); +} + +static void HandleCloudReopen(struct fuse_file_info *fi, struct CloudDiskFuseData *data, + shared_ptr inoPtr, CloudOpenParams cloudOpenParams, fuse_req_t req) +{ + auto metaBase = cloudOpenParams.metaBase; + auto filePtr = cloudOpenParams.filePtr; + if (metaBase.fileType != FILE_TYPE_CONTENT) { + string path = CloudFileUtils::GetLocalFilePath(inoPtr->cloudId, inoPtr->bundleName, data->userId); + unsigned int flags = GetFileOpenFlags(fi->flags); + int32_t fd = open(path.c_str(), flags); + if (fd < 0) { + LOGE("failed to open local file, errno: %{public}d", errno); + filePtr->readSession->sessionCount--; + fuse_reply_err(req, errno); + return; + } + filePtr->type = CLOUD_DISK_FILE_TYPE_LOCAL; + filePtr->fd = fd; + filePtr->readSession->sessionCount--; + } else { + filePtr->type = CLOUD_DISK_FILE_TYPE_CLOUD; + } + fuse_reply_open(req, fi); +} + static void CloudOpen(fuse_req_t req, shared_ptr inoPtr, struct fuse_file_info *fi, string path, fuse_ino_t ino) { @@ -560,26 +622,26 @@ static void CloudOpen(fuse_req_t req, shared_ptr inoPtr, } auto filePtr = InitFileAttr(data, fi); CloudOpenParams cloudOpenParams = {metaBase, metaFile, filePtr}; + std::unique_lock lck(inoPtr->sessionLock); if (GetNewSession(inoPtr, path, data, database, cloudOpenParams)) { FileOperationsHelper::PutCloudDiskFile(data, filePtr, fi->fh); fuse_inval(data->se, inoPtr->parent, ino, inoPtr->fileName); return (void) fuse_reply_err(req, EPERM); } + HandleOpenErrorParams handleOpenErrorParams = {filePtr, inoPtr, ino}; if (filePtr->readSession) { + if (filePtr->readSession->sessionCount > 1) { + return HandleCloudReopen(fi, data, inoPtr, cloudOpenParams, req); + } auto ret = DoCloudOpen(req, fi, inoPtr, data, cloudOpenParams); if (!ret) { fuse_reply_open(req, fi); } else { - filePtr->readSession = nullptr; - FileOperationsHelper::PutCloudDiskFile(data, filePtr, fi->fh); - fuse_inval(data->se, inoPtr->parent, ino, inoPtr->fileName); + HandleOpenFail(handleOpenErrorParams, path, data, fi); return (void) fuse_reply_err(req, ret); } } else { - CLOUD_FILE_FAULT_REPORT(CloudFile::CloudFileFaultInfo{"", CloudFile::FaultOperation::OPEN, - CloudFile::FaultType::DRIVERKIT, EPERM, "readSession is null"}); - FileOperationsHelper::PutCloudDiskFile(data, filePtr, fi->fh); - fuse_inval(data->se, inoPtr->parent, ino, inoPtr->fileName); + HandleSessionNull(handleOpenErrorParams, data, fi); return (void) fuse_reply_err(req, EPERM); } } @@ -1850,6 +1912,23 @@ static int32_t HandleLocalClose(fuse_req_t req, shared_ptr inoPt return 0; } +static void ReleaseHandler(std::shared_ptr filePtr, std::shared_ptr inoPtr, + CloudDiskFuseData *data) +{ + std::unique_lock lck(inoPtr->sessionLock); + filePtr->readSession->sessionCount--; + if (filePtr->readSession->sessionCount == 0) { + bool res = filePtr->readSession->Close(false); + if (!res) { + LOGE("close error"); + } + string path = CloudFileUtils::GetLocalDKCachePath(inoPtr->cloudId, inoPtr->bundleName, data->userId); + ErasePathCache(path, data); + filePtr->readSession = nullptr; + LOGD("readSession released"); + } +} + void FileOperationsCloud::Release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); @@ -1882,12 +1961,7 @@ void FileOperationsCloud::Release(fuse_req_t req, fuse_ino_t ino, struct fuse_fi return (void)fuse_reply_err(req, ret); } } else if (filePtr->type == CLOUD_DISK_FILE_TYPE_CLOUD && filePtr->readSession != nullptr) { - bool res = filePtr->readSession->Close(false); - if (!res) { - LOGE("close error"); - } - filePtr->readSession = nullptr; - LOGD("readSession released"); + ReleaseHandler(filePtr, inoPtr, data); } FileOperationsHelper::PutCloudDiskFile(data, filePtr, fi->fh); } diff --git a/test/unittests/cloud_disk/BUILD.gn b/test/unittests/cloud_disk/BUILD.gn index 2f6830c0a16a6ed9be7d5031977b5d2c8cbe1e98..fa51baf8af142f3e561f99634a930d889f8df1e8 100644 --- a/test/unittests/cloud_disk/BUILD.gn +++ b/test/unittests/cloud_disk/BUILD.gn @@ -139,6 +139,71 @@ ohos_unittest("file_operations_cloud_test") { use_exceptions = true } +ohos_unittest("file_operations_cloud_static_test") { + module_out_path = "dfs_service/dfs_service" + + include_dirs = [ + "${distributedfile_path}/adapter/cloud_adapter_example/include", + "${distributedfile_path}/interfaces/inner_api/native/cloudsync_kit_inner", + "${distributedfile_path}/utils/log/include", + "${distributedfile_path}/utils/ioctl/include", + "${services_path}/clouddisk_database/include", + "${services_path}/cloudfiledaemon/include/cloud_disk/", + "${services_path}/cloudfiledaemon/src/cloud_disk/", + "mock", + ] + +sources = [ + "${distributedfile_path}/services/cloudfiledaemon/src/cloud_disk/file_operations_helper.cpp", + "${distributedfile_path}/test/unittests/cloudsync_sa/mock/cloud_file_utils_mock.cpp", + "${services_path}/cloudfiledaemon/src/cloud_disk/account_status.cpp", + "${services_path}/cloudfiledaemon/src/cloud_disk/database_manager.cpp", + "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_base.cpp", + "${services_path}/cloudfiledaemon/src/cloud_disk/file_operations_local.cpp", + "${services_path}/cloudfiledaemon/src/cloud_disk/fuse_operations.cpp", + "file_operations_cloud_static_test.cpp", + "mock/libfuse_mock.cpp", + ] + + deps = [ + "${clouddisk_database_path}:clouddisk_database", + "${innerkits_native_path}/cloud_file_kit_inner:cloudfile_kit", + "${utils_path}:libdistributedfiledentry", + "${utils_path}:libdistributedfileutils", + "${utils_path}:libdistributedfileutils_lite", + ] + + external_deps = [ + "ability_base:want", + "ability_runtime:dataobs_manager", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "init:libbegetutil", + "json:nlohmann_json_static", + "libfuse:libfuse", + "relational_store:native_rdb", + ] + + defines = [ + "private=public", + "LOG_DOMAIN=0xD004308", + "LOG_TAG=\"CLOUD_DAEMON_API\"", + ] + + if (cloudsync_service_hicollie_enable) { + external_deps += [ "hicollie:libhicollie" ] + defines += [ "HICOLLIE_ENABLE" ] + } + + use_exceptions = true +} + ohos_unittest("database_manager_test") { module_out_path = "dfs_service/dfs_service" @@ -662,6 +727,7 @@ group("cloud_disk_test") { ":database_manager_test", ":file_operations_base_test", ":file_operations_cloud_test", + ":file_operations_cloud_static_test", ":file_operations_helper_test", ":file_operations_local_test", ":fuse_operations_test", diff --git a/test/unittests/cloud_disk/file_operations_cloud_static_test.cpp b/test/unittests/cloud_disk/file_operations_cloud_static_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac1894a50aa31fc946dcb23254949a24aba5b300 --- /dev/null +++ b/test/unittests/cloud_disk/file_operations_cloud_static_test.cpp @@ -0,0 +1,560 @@ +/* + * 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 +#include +#include +#include + +#include "assistant.h" +#include "dfs_error.h" +#include "file_operations_cloud.cpp" + +namespace OHOS::FileManagement::CloudDisk::Test { +using namespace testing; +using namespace testing::ext; + +constexpr int32_t USER_ID = 100; +class FileOperationsCloudStaticTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr fileOperationsCloud_ = nullptr; + static inline shared_ptr insMock = nullptr; +}; + +void FileOperationsCloudStaticTest::SetUpTestCase(void) +{ + fileOperationsCloud_ = make_shared(); + insMock = make_shared(); + Assistant::ins = insMock; + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FileOperationsCloudStaticTest::TearDownTestCase(void) +{ + fileOperationsCloud_ = nullptr; + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FileOperationsCloudStaticTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void FileOperationsCloudStaticTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: SetSessionCountTest001 + * @tc.desc: Verify the SetSessionCount function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, SetSessionCountTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "SetSessionCountTest001 Start"; + try { + string path = "/data"; + string cloudId = "100"; + string assets = "content"; + struct CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr filePtr = make_shared(); + SessionCountParams sessionParam = {path, cloudId, assets}; + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + data->readSessionCache[path] = readSession; + data->readSessionCache[path]->sessionCount = 1; + + SetSessionCount(data, sessionParam, filePtr, database); + EXPECT_EQ(filePtr->readSession->sessionCount, data->readSessionCache[path]->sessionCount); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "SetSessionCountTest001 ERROR"; + } + GTEST_LOG_(INFO) << "SetSessionCountTest001 End"; +} + +/** + * @tc.name: SetSessionCountTest002 + * @tc.desc: Verify the SetSessionCount function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, SetSessionCountTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "SetSessionCountTest002 Start"; + try { + string path = "/data"; + string cloudId = "100"; + string assets = "content"; + struct CloudDiskFuseData *data = new CloudDiskFuseData; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr filePtr = make_shared(); + SessionCountParams sessionParam = {path, cloudId, assets}; + if (data->readSessionCache.find(path) != data->readSessionCache.end()) { + data->readSessionCache.erase(path); + } + + SetSessionCount(data, sessionParam, filePtr, database); + EXPECT_EQ(filePtr->readSession->sessionCount, 1); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "SetSessionCountTest002 ERROR"; + } + GTEST_LOG_(INFO) << "SetSessionCountTest002 End"; +} + +/** + * @tc.name: SetSessionCountTest003 + * @tc.desc: Verify the SetSessionCount function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, SetSessionCountTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "SetSessionCountTest003 Start"; + try { + string path = "/data"; + string cloudId = "100"; + string assets = "content"; + struct CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr filePtr = make_shared(); + SessionCountParams sessionParam = {path, cloudId, assets}; + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + data->readSessionCache[path] = readSession; + data->readSessionCache[path]->sessionCount = 2; + + SetSessionCount(data, sessionParam, filePtr, database); + EXPECT_EQ(filePtr->readSession->sessionCount, data->readSessionCache[path]->sessionCount); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "SetSessionCountTest003 ERROR"; + } + GTEST_LOG_(INFO) << "SetSessionCountTest003 End"; +} + + +/** + * @tc.name: ErasePathCacheTest001 + * @tc.desc: Verify the ErasePathCache function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, ErasePathCacheTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ErasePathCacheTest001 Start"; + try { + string path = "/data"; + struct CloudDiskFuseData *data = new CloudDiskFuseData; + if (data->readSessionCache.find(path) != data->readSessionCache.end()) { + data->readSessionCache.erase(path); + } + + ErasePathCache(path, data); + EXPECT_EQ(data->readSessionCache.count(path), 0); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ErasePathCacheTest001 ERROR"; + } + GTEST_LOG_(INFO) << "ErasePathCacheTest001 End"; +} + +/** + * @tc.name: ErasePathCacheTest002 + * @tc.desc: Verify the ErasePathCache function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, ErasePathCacheTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ErasePathCacheTest002 Start"; + try { + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + string cloudId = "100"; + string assets = "content"; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr filePtr = make_shared(); + struct SessionCountParams sessionParam = {path, cloudId, assets}; + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + data->readSessionCache[path] = readSession; + + ErasePathCache(path, data); + EXPECT_EQ(data->readSessionCache.count(path), 0); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ErasePathCacheTest002 ERROR"; + } + GTEST_LOG_(INFO) << "ErasePathCacheTest002 End"; +} + +/** + * @tc.name: GetNewSessionTest001 + * @tc.desc: Verify the GetNewSession function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, GetNewSessionTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetNewSessionTest001 Start"; + try { + std::shared_ptr inoPtr = make_shared(); + inoPtr->cloudId = "123"; + inoPtr->bundleName = "com.example.test"; + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(0, "com.example.test"); + MetaBase metaBase; + metaBase.fileType = FILE_TYPE_THUMBNAIL; + std::shared_ptr metaFile = make_shared(0, "com.example.test", "123"); + std::shared_ptr filePtr = make_shared(); + CloudOpenParams cloudOpenParams = {metaBase, metaFile, filePtr}; + + auto ret = GetNewSession(inoPtr, path, data, database, cloudOpenParams); + EXPECT_EQ(ret, E_RDB); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetNewSessionTest001 ERROR"; + } + GTEST_LOG_(INFO) << "GetNewSessionTest001 End"; +} + +/** + * @tc.name: GetNewSessionTest002 + * @tc.desc: Verify the GetNewSession function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, GetNewSessionTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetNewSessionTest002 Start"; + try { + std::shared_ptr inoPtr = make_shared(); + inoPtr->cloudId = "123"; + inoPtr->bundleName = "com.example.test"; + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(0, "com.example.test"); + MetaBase metaBase; + metaBase.fileType = FILE_TYPE_CONTENT; + std::shared_ptr metaFile = make_shared(0, "com.example.test", "123"); + std::shared_ptr filePtr = make_shared(); + CloudOpenParams cloudOpenParams = {metaBase, metaFile, filePtr}; + + auto ret = GetNewSession(inoPtr, path, data, database, cloudOpenParams); + EXPECT_EQ(filePtr->readSession->sessionCount, data->readSessionCache[path]->sessionCount); + EXPECT_EQ(ret, E_OK); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetNewSessionTest002 ERROR"; + } + GTEST_LOG_(INFO) << "GetNewSessionTest002 End"; +} + +/** + * @tc.name: ReleaseHandlerTest001 + * @tc.desc: Verify the ReleaseHandle function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, ReleaseHandlerTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ReleaseHandlerTest001 Start"; + try { + string path = "/data"; + string cloudId = "100"; + string assets = "content"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr inoPtr = make_shared(); + inoPtr->bundleName = "Test"; + inoPtr->cloudId = "100"; + std::shared_ptr filePtr = make_shared(); + struct SessionCountParams sessionParam = {path, cloudId, assets}; + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + filePtr->readSession = readSession; + filePtr->readSession->sessionCount = 1; + + ReleaseHandler(filePtr, inoPtr, data); + EXPECT_EQ(filePtr->readSession, nullptr); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ReleaseHandlerTest001 ERROR"; + } + GTEST_LOG_(INFO) << "ReleaseHandlerTest001 End"; +} + +/** + * @tc.name: ReleaseHandlerTest002 + * @tc.desc: Verify the ReleaseHandle function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, ReleaseHandlerTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ReleaseHandlerTest002 Start"; + try { + string path = "/data"; + string cloudId = "100"; + string assets = "content"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr inoPtr = make_shared(); + inoPtr->bundleName = "Test"; + inoPtr->cloudId = "100"; + std::shared_ptr filePtr = make_shared(); + struct SessionCountParams sessionParam = {path, cloudId, assets}; + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + filePtr->readSession = readSession; + filePtr->readSession->sessionCount = 2; + + ReleaseHandler(filePtr, inoPtr, data); + EXPECT_EQ(filePtr->readSession->sessionCount, 1); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ReleaseHandlerTest002 ERROR"; + } + GTEST_LOG_(INFO) << "ReleaseHandlerTest002 End"; +} + +/** + * @tc.name: ReleaseHandlerTest003 + * @tc.desc: Verify the ReleaseHandle function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, ReleaseHandlerTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "ReleaseHandlerTest003 Start"; + try { + string path = "/data"; + string cloudId = "100"; + string assets = "content"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + std::shared_ptr inoPtr = make_shared(); + inoPtr->bundleName = "Test"; + inoPtr->cloudId = "100"; + std::shared_ptr filePtr = make_shared(); + struct SessionCountParams sessionParam = {path, cloudId, assets}; + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + filePtr->readSession = readSession; + filePtr->readSession->sessionCount = 0; + + ReleaseHandler(filePtr, inoPtr, data); + EXPECT_EQ(filePtr->readSession->sessionCount, -1); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "ReleaseHandlerTest003 ERROR"; + } + GTEST_LOG_(INFO) << "ReleaseHandlerTest003 End"; +} + +/** + * @tc.name: HandleOpenFailTest001 + * @tc.desc: Verify the ReleaseHandle function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, HandleOpenFailTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleOpenFailTest001 Start"; + try { + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + fuse_file_info *fi = new fuse_file_info; + std::shared_ptr filePtr = make_shared(); + filePtr->readSession = nullptr; + std::shared_ptr inoPtr = make_shared(); + inoPtr->fileName = "Test"; + fuse_ino_t ino = 0; + HandleOpenErrorParams params = {filePtr, inoPtr, ino}; + string cloudId = "100"; + string assets = "content"; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + data->readSessionCache[path] = readSession; + + HandleOpenFail(params, path, data, fi); + EXPECT_EQ(data->readSessionCache.count(path), 0); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleOpenFailTest001 ERROR"; + } + GTEST_LOG_(INFO) << "HandleOpenFailTest001 End"; +} + +/** + * @tc.name: HandleSessionNullTest001 + * @tc.desc: Verify the HandleSessionNull function + * @tc.type: FUNC + * @tc.require: issuesI91IOG + */ +HWTEST_F(FileOperationsCloudStaticTest, HandleSessionNullTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleSessionNullTest001 Start"; + try { + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + fuse_file_info *fi = new fuse_file_info; + std::shared_ptr filePtr = make_shared(); + filePtr->readSession = nullptr; + std::shared_ptr inoPtr = make_shared(); + inoPtr->fileName = "Test"; + fuse_ino_t ino = 0; + HandleOpenErrorParams params = {filePtr, inoPtr, ino}; + string cloudId = "100"; + string assets = "content"; + data->userId = 100; + std::shared_ptr database = make_shared(100, "test"); + auto readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + data->readSessionCache[path] = readSession; + + HandleSessionNull(params, data, fi); + EXPECT_EQ(data->readSessionCache[path], readSession); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleSessionNullTest001 ERROR"; + } + GTEST_LOG_(INFO) << "HandleSessionNullTest001 End"; +} + +/** + * @tc.name: HandleCloudReopenTest001 + * @tc.desc: Verify the HandleCloudReopen function + * @tc.type: FUNC + * @tc.require: I6H5MH + */ +HWTEST_F(FileOperationsCloudStaticTest, HandleCloudReopenTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCloudReopenTest001 start"; + try { + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + fuse_file_info *fi = new fuse_file_info; + std::shared_ptr filePtr = make_shared(); + filePtr->readSession = nullptr; + filePtr->type = CLOUD_DISK_FILE_TYPE_UNKNOWN; + std::shared_ptr inoPtr = make_shared(); + inoPtr->fileName = "Test"; + MetaBase metaBase(inoPtr->fileName); + metaBase.fileType = FILE_TYPE_CONTENT; + std::shared_ptr metaFile = make_shared(0, "com.example.test", "123"); + CloudOpenParams params = {metaBase, metaFile, filePtr}; + fuse_req_t req = nullptr; + EXPECT_CALL(*insMock, fuse_reply_open(_, _)).WillOnce(Return(E_OK)); + + HandleCloudReopen(fi, data, inoPtr, params, req); + EXPECT_EQ(filePtr->type, CLOUD_DISK_FILE_TYPE_CLOUD); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCloudReopenTest001 failed"; + } + GTEST_LOG_(INFO) << "HandleCloudReopenTest001 end"; +} + +/** + * @tc.name: HandleCloudReopenTest002 + * @tc.desc: Verify the HandleCloudReopen function + * @tc.type: FUNC + * @tc.require: I6H5MH + */ +HWTEST_F(FileOperationsCloudStaticTest, HandleCloudReopenTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCloudReopenTest002 start"; + try { + string cloudId = "100"; + string assets = "content"; + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 0; + fuse_file_info *fi = new fuse_file_info; + std::shared_ptr filePtr = make_shared(); + filePtr->readSession = nullptr; + filePtr->type = CLOUD_DISK_FILE_TYPE_UNKNOWN; + std::shared_ptr inoPtr = make_shared(); + inoPtr->fileName = "Test"; + MetaBase metaBase(inoPtr->fileName); + metaBase.fileType = FILE_TYPE_LCD; + std::shared_ptr metaFile = make_shared(0, "com.example.test", "123"); + CloudOpenParams params = {metaBase, metaFile, filePtr}; + fuse_req_t req = nullptr; + std::shared_ptr database = make_shared(100, "test"); + filePtr->readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + EXPECT_CALL(*insMock, fuse_reply_err(_, _)).WillOnce(Return(E_OK)); + + HandleCloudReopen(fi, data, inoPtr, params, req); + EXPECT_EQ(filePtr->type, CLOUD_DISK_FILE_TYPE_UNKNOWN); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCloudReopenTest002 failed"; + } + GTEST_LOG_(INFO) << "HandleCloudReopenTest002 end"; +} + +/** + * @tc.name: HandleCloudReopenTest003 + * @tc.desc: Verify the HandleCloudReopen function + * @tc.type: FUNC + * @tc.require: I6H5MH + */ +HWTEST_F(FileOperationsCloudStaticTest, HandleCloudReopenTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCloudReopenTest003 start"; + try { + string cloudId = "100"; + string assets = "content"; + string path = "/data"; + CloudDiskFuseData *data = new CloudDiskFuseData; + data->userId = 100; + fuse_file_info *fi = new fuse_file_info; + std::shared_ptr filePtr = make_shared(); + filePtr->readSession = nullptr; + filePtr->type = CLOUD_DISK_FILE_TYPE_UNKNOWN; + std::shared_ptr inoPtr = make_shared(); + inoPtr->fileName = "Test"; + MetaBase metaBase(inoPtr->fileName); + metaBase.fileType = FILE_TYPE_LCD; + std::shared_ptr metaFile = make_shared(0, "com.example.test", "123"); + CloudOpenParams params = {metaBase, metaFile, filePtr}; + fuse_req_t req = nullptr; + std::shared_ptr database = make_shared(100, "test"); + filePtr->readSession = database->NewAssetReadSession(data->userId, "file", cloudId, assets, path); + EXPECT_CALL(*insMock, fuse_reply_open(_, _)).WillOnce(Return(E_OK)); + + HandleCloudReopen(fi, data, inoPtr, params, req); + EXPECT_EQ(filePtr->type, CLOUD_DISK_FILE_TYPE_LOCAL); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCloudReopenTest003 failed"; + } + GTEST_LOG_(INFO) << "HandleCloudReopenTest003 end"; +} +} \ No newline at end of file