diff --git a/services/clouddiskservice/monitor/include/disk_monitor.h b/services/clouddiskservice/monitor/include/disk_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..dfea9291894c17f20c45cecfe1879b47949c4ad7 --- /dev/null +++ b/services/clouddiskservice/monitor/include/disk_monitor.h @@ -0,0 +1,69 @@ +/* + * 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_FILEMANAGEMENT_DISK_MONITOR_H +#define OHOS_FILEMANAGEMENT_DISK_MONITOR_H + +#include +#include +#include + +#include "disk_types.h" +#include "ffrt_inner.h" +#include "nocopyable.h" + +namespace OHOS::FileManagement::CloudDiskService { +class DiskMonitor : public NoCopyable { +public: + static DiskMonitor &GetInstance(); + bool StartMonitor(int32_t userId); + void StopMonitor(); + +private: + DiskMonitor() = default; + ~DiskMonitor() = default; + bool InitFanotify(); + void InitStatus(int32_t userId); + void CollectEvents(); + void HandleEvents(int32_t mountFd, char eventsBuf[], size_t dataLen); + void EventProcess(struct fanotify_event_metadata *metaData, const std::string &filePath); + // events handle + void HandleCreate(const std::string &filePath); + void HandleDelete(const std::string &filePath); + void HandleMoveFrom(const std::string &filePath); + void HandleMoveTo(const std::string &filePath); + void HandleCloseWrite(const std::string &filePath); + void PostEvent(const EventInfo &eventInfo); + // events filter + std::pair GetSyncFolderIndex(const std::string &filePath); + bool IsInBlockList(const std::string &path); + +private: + // monitor status + int32_t userId_{-1}; + int32_t fanotifyFd_{-1}; + DIR *mountFp_{nullptr}; + int32_t mountFd_{-1}; // will be closed automatically after close(DIR*) + bool isRunning_{true}; + ffrt::mutex mutex_; + // events handle + EventInfo oldEventInfo_; + bool oldIsSyncFolder_{false}; + // events filter + std::string syncFolderPrefix_; + std::vector blockList_; +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif diff --git a/services/clouddiskservice/monitor/include/disk_types.h b/services/clouddiskservice/monitor/include/disk_types.h new file mode 100644 index 0000000000000000000000000000000000000000..4bbceeb756589ea4ba207b14e4c0984177144617 --- /dev/null +++ b/services/clouddiskservice/monitor/include/disk_types.h @@ -0,0 +1,63 @@ +/* + * 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_FILEMANAGEMENT_DISK_TYPES_H +#define OHOS_FILEMANAGEMENT_DISK_TYPES_H +#include +#include +#include + +#include "cloud_disk_common.h" + +namespace OHOS::FileManagement::CloudDiskService { +constexpr int64_t SECOND_TO_MILLISECOND = 1e3; +constexpr int64_t MILLISECOND_TO_NANOSECOND = 1e6; + +static uint64_t UTCTimeMilliSeconds() +{ + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + return t.tv_sec * SECOND_TO_MILLISECOND + t.tv_nsec / MILLISECOND_TO_NANOSECOND; +} + +struct EventInfo { + int32_t userId{-1}; + uint32_t syncFolderIndex{0}; + std::string path; + std::string name; + OperationType operateType{OperationType::OPERATION_MAX}; + uint64_t timestamp{0}; + + EventInfo() {} + EventInfo(int32_t uid, int32_t syncFolder, OperationType type, const std::string &filePath) + : userId(uid), syncFolderIndex(syncFolder), operateType(type) + { + path = std::filesystem::path(filePath).parent_path().string(); + name = std::filesystem::path(filePath).filename().string(); + timestamp = UTCTimeMilliSeconds(); + } + + void Reset() + { + userId = -1; + syncFolderIndex = 0; + path = ""; + name = ""; + operateType = OperationType::OPERATION_MAX; + timestamp = 0; + } +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif diff --git a/services/clouddiskservice/monitor/include/disk_utils.h b/services/clouddiskservice/monitor/include/disk_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..b196bfbc4bf36ef8695b28ab209b1cdea33c428d --- /dev/null +++ b/services/clouddiskservice/monitor/include/disk_utils.h @@ -0,0 +1,33 @@ +/* + * 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_FILEMANAGEMENT_DISK_UTILS_H +#define OHOS_FILEMANAGEMENT_DISK_UTILS_H + +#include +#include +#include +#include + +namespace OHOS::FileManagement::CloudDiskService { +class DiskUtils { +public: + static bool ExtractFileName(int type, std::string &fileName, struct file_handle *fileHandle); + static std::string GetFilePath(int32_t eventFd, const std::string &fileName); + static void CloseFd(int &fd); + static void CloseDir(DIR *&dir); +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif diff --git a/services/clouddiskservice/monitor/src/disk_monitor.cpp b/services/clouddiskservice/monitor/src/disk_monitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c73f3907fa9edc9c6c19c95b7f257d73e5e24158 --- /dev/null +++ b/services/clouddiskservice/monitor/src/disk_monitor.cpp @@ -0,0 +1,322 @@ +/* + * 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 "disk_monitor.h" + +#include +#include +#include + +#include "cloud_disk_service_syncfolder.h" +#include "cloud_disk_sync_folder.h" +#include "disk_utils.h" +#include "ffrt_inner.h" +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; +namespace { +constexpr uint32_t INIT_FLAGS = FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME | FAN_UNLIMITED_QUEUE; +constexpr uint32_t INIT_EVENT_FLAGS = O_RDONLY | O_LARGEFILE; +constexpr uint32_t MARK_FLAGS = FAN_MARK_ADD | FAN_MARK_FILESYSTEM; +constexpr uint64_t MARK_MASK = FAN_CREATE | FAN_DELETE | FAN_MOVED_FROM | FAN_MOVED_TO | FAN_ONDIR | FAN_CLOSE_WRITE; +constexpr int32_t INVALID_SYNC_FOLDER = 0; +constexpr uint32_t EVENTS_BUF_SIZE = 4096; +const string MOUNT_PATH = "/data/service"; +const string DATA_SERVICE_EL2 = "/data/service/el2/"; +const string HMDFS_DOCS = "/hmdfs/account/files/Docs"; +const vector BLACK_DIRS = {"/.Trash", "/.Recent", "/.thumbs", "/HO_DATA_EXT_MISC"}; +} // namespace + +DiskMonitor &DiskMonitor::GetInstance() +{ + static DiskMonitor instance_; + return instance_; +} + +bool DiskMonitor::StartMonitor(int32_t userId) +{ + { + lock_guard lck(mutex_); + if (isRunning_) { + LOGE("monitor is running, do not start again"); + return false; + } + LOGI("Start monitor: %{public}d", userId); + if (!InitFanotify()) { + return false; + } + InitStatus(userId); + } + ffrt::submit([this] { this->CollectEvents(); }); + LOGI("Start monitor finished"); + return true; +} + +void DiskMonitor::StopMonitor() +{ + lock_guard lck(mutex_); + userId_ = -1; + isRunning_ = false; + syncFolderPrefix_.clear(); + blockList_.clear(); + // clean fd + DiskUtils::CloseFd(fanotifyFd_); + DiskUtils::CloseDir(mountFp_); +} + +void DiskMonitor::InitStatus(int32_t userId) +{ + userId_ = userId; + isRunning_ = true; + syncFolderPrefix_ = DATA_SERVICE_EL2 + to_string(userId) + HMDFS_DOCS; + for (auto &it : BLACK_DIRS) { + blockList_.push_back(DATA_SERVICE_EL2 + to_string(userId) + HMDFS_DOCS + it); + } +} + +bool DiskMonitor::InitFanotify() +{ + LOGI("init start"); + fanotifyFd_ = fanotify_init(INIT_FLAGS, INIT_EVENT_FLAGS); + if (fanotifyFd_ == -1) { + LOGE("disk monitor init failed, errno: %{public}d", errno); + return false; + } + if (fanotify_mark(fanotifyFd_, MARK_FLAGS, MARK_MASK, AT_FDCWD, MOUNT_PATH.c_str()) == -1) { + LOGE("fanotify_mark failed, errno: %{public}d", errno); + DiskUtils::CloseFd(fanotifyFd_); + return false; + } + mountFp_ = opendir(MOUNT_PATH.c_str()); + if (mountFp_ == nullptr) { + LOGE("open dir failed, errno: %{public}d", errno); + DiskUtils::CloseFd(fanotifyFd_); + return false; + } + mountFd_ = dirfd(mountFp_); + if (mountFd_ == -1) { + LOGE("get dirfd failed, errno: %{public}d", errno); + DiskUtils::CloseFd(fanotifyFd_); + DiskUtils::CloseDir(mountFp_); + return false; + } + LOGI("Init end"); + return true; +} + +void DiskMonitor::CollectEvents() +{ + while (isRunning_) { + char eventsBuf[EVENTS_BUF_SIZE]{}; + ssize_t dataLen = read(fanotifyFd_, eventsBuf, sizeof(eventsBuf)); + if (dataLen == -1 && errno != EAGAIN) { + LOGE("read failed, errno: %{public}d", errno); + continue; + } + if (dataLen == 0) { + LOGI("no data to read"); + continue; + } + + HandleEvents(mountFd_, eventsBuf, dataLen); + } +} + +void DiskMonitor::HandleEvents(int32_t mountFd, char eventsBuf[], size_t dataLen) +{ + for (struct fanotify_event_metadata *metaData = reinterpret_cast(eventsBuf); + FAN_EVENT_OK(metaData, dataLen); metaData = FAN_EVENT_NEXT(metaData, dataLen)) { + struct fanotify_event_info_fid *fID = reinterpret_cast(metaData + 1); + struct file_handle *fileHandle = reinterpret_cast(fID->handle); + if (fileHandle == nullptr) { + LOGE("fileHandle is null"); + continue; + } + + // get file name + string fileName; + if (!DiskUtils::ExtractFileName(fID->hdr.info_type, fileName, fileHandle)) { + continue; + } + + // get file path + int eventFd = open_by_handle_at(mountFd, fileHandle, O_RDONLY); + if (eventFd == -1) { + continue; + } + string filePath = DiskUtils::GetFilePath(eventFd, fileName); + if (filePath.empty()) { + close(eventFd); + continue; + } + + EventProcess(metaData, filePath); + close(eventFd); + } +} + +void DiskMonitor::EventProcess(struct fanotify_event_metadata *metaData, const string &filePath) +{ + if (metaData->mask & FAN_CREATE) { + HandleCreate(filePath); + } else if (metaData->mask & FAN_DELETE) { + HandleDelete(filePath); + } else if (metaData->mask & FAN_MOVED_FROM) { + HandleMoveFrom(filePath); + } else if (metaData->mask & FAN_MOVED_TO) { + HandleMoveTo(filePath); + } else if (metaData->mask & FAN_CLOSE_WRITE) { + HandleCloseWrite(filePath); + } +} + +void DiskMonitor::HandleCreate(const string &filePath) +{ + auto [syncFolderIndex, _] = GetSyncFolderIndex(filePath); + if (syncFolderIndex == INVALID_SYNC_FOLDER) { + return; + } + auto eventInfo = EventInfo(userId_, syncFolderIndex, OperationType::CREATE, filePath); + PostEvent(eventInfo); +} + +void DiskMonitor::HandleDelete(const string &filePath) +{ + auto [syncFolderIndex, isSyncFolder] = GetSyncFolderIndex(filePath); + if (syncFolderIndex == INVALID_SYNC_FOLDER) { + return; + } + OperationType type = isSyncFolder ? OperationType::SYNC_FOLDER_INVALID : OperationType::DELETE; + auto eventInfo = EventInfo(userId_, syncFolderIndex, type, filePath); + PostEvent(eventInfo); +} + +void DiskMonitor::HandleMoveFrom(const string &filePath) +{ + auto [syncFolderIndex, isSyncFolder] = GetSyncFolderIndex(filePath); + if (syncFolderIndex == INVALID_SYNC_FOLDER) { + return; + } + { + lock_guard lck(mutex_); + oldEventInfo_ = EventInfo(userId_, syncFolderIndex, OperationType::MOVE_FROM, filePath); + oldIsSyncFolder_ = isSyncFolder; + } +} + +/* + * old is not in sync folder, new is not in sync folder, skip + * old is not in sync folder, new is in sync folder, create->new + * old is in sync folder, new is not in sync folder: + * 1. old is sync folder, sync_folder_invalid->old + * 2. old is not sync folder, delete->old + * old is in sync folder, new is in sync folder, sync root is the same, move_from->old + move_to->new + * old is in sync folder, new is in sync folder, sync root is not the same + * 1. old is sync folder, sync_folder_invalid->old + create->new + * 2. old is not sync folder, delete->old + create->new + */ +void DiskMonitor::HandleMoveTo(const string &filePath) +{ + auto [syncFolderIndex, _] = GetSyncFolderIndex(filePath); + auto eventInfo = EventInfo(userId_, syncFolderIndex, OperationType::MOVE_TO, filePath); + do { + // old is not in sync folder + if (oldEventInfo_.syncFolderIndex == INVALID_SYNC_FOLDER) { + if (eventInfo.syncFolderIndex == INVALID_SYNC_FOLDER) { + break; + } + eventInfo.operateType = OperationType::CREATE; + PostEvent(eventInfo); + break; + } + + // old is in sync folder, new is not in sync folder + if (eventInfo.syncFolderIndex == INVALID_SYNC_FOLDER) { + OperationType type = oldIsSyncFolder_ ? OperationType::SYNC_FOLDER_INVALID : OperationType::DELETE; + oldEventInfo_.operateType = type; + PostEvent(oldEventInfo_); + break; + } + + // old is in sync folder, new is in sync folder, sync root is the same + if (oldEventInfo_.syncFolderIndex == eventInfo.syncFolderIndex) { + oldEventInfo_.operateType = OperationType::MOVE_FROM; + eventInfo.operateType = OperationType::MOVE_TO; + PostEvent(oldEventInfo_); + PostEvent(eventInfo); + break; + } + + // old is in sync folder, new is in sync folder, sync root is not the same + OperationType type = oldIsSyncFolder_ ? OperationType::SYNC_FOLDER_INVALID : OperationType::DELETE; + oldEventInfo_.operateType = type; + eventInfo.operateType = OperationType::CREATE; + PostEvent(oldEventInfo_); + PostEvent(eventInfo); + } while (0); + { + lock_guard lck(mutex_); + oldEventInfo_.Reset(); + oldIsSyncFolder_ = false; + } +} + +void DiskMonitor::HandleCloseWrite(const string &filePath) +{ + auto [syncFolderIndex, _] = GetSyncFolderIndex(filePath); + if (syncFolderIndex == INVALID_SYNC_FOLDER) { + return; + } + auto eventInfo = EventInfo(userId_, syncFolderIndex, OperationType::CLOSE_WRITE, filePath); + PostEvent(eventInfo); +} + +pair DiskMonitor::GetSyncFolderIndex(const string &filePath) +{ + if (IsInBlockList(filePath)) { + return {INVALID_SYNC_FOLDER, false}; + } + for (auto &it : CloudDiskSyncFolder::GetInstance().GetSyncFolderMap()) { + if (filePath == it.second.path) { + return {it.first, true}; + } + // sync foler is parent dir + if (filePath.find(it.second.path + "/") == 0) { + return {it.first, false}; + } + } + return {INVALID_SYNC_FOLDER, false}; +} + +bool DiskMonitor::IsInBlockList(const string &path) +{ + if (path.find(syncFolderPrefix_) != 0) { + return true; + } + for (auto &it : blockList_) { + if (path.find(it) == 0) { + return true; + } + } + return false; +} + +void DiskMonitor::PostEvent(const EventInfo &eventInfo) +{ + LOGD("opt: %{public}d path: %{public}s name: %{public}s", static_cast(eventInfo.operateType), + eventInfo.path.c_str(), eventInfo.name.c_str()); + CloudDiskServiceSyncFolder::SetSyncFolderChanges(eventInfo); +} +} // namespace OHOS::FileManagement::CloudDiskService diff --git a/services/clouddiskservice/monitor/src/disk_utils.cpp b/services/clouddiskservice/monitor/src/disk_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa9995f250499f20ca418c13eef62189f45c7e34 --- /dev/null +++ b/services/clouddiskservice/monitor/src/disk_utils.cpp @@ -0,0 +1,72 @@ +/* + * 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 "disk_utils.h" + +#include +#include + +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; +const string PROC_SELF_FD = "/proc/self/fd/"; + +bool DiskUtils::ExtractFileName(int type, string &fileName, struct file_handle *fileHandle) +{ + if (type == FAN_EVENT_INFO_TYPE_FID || type == FAN_EVENT_INFO_TYPE_DFID) { + fileName.clear(); + } else if (type == FAN_EVENT_INFO_TYPE_DFID_NAME) { + fileName = reinterpret_cast(fileHandle->f_handle + fileHandle->handle_bytes); + } else { + return false; + } + return true; +} + +string DiskUtils::GetFilePath(int32_t eventFd, const string &fileName) +{ + char eventFilePath[PATH_MAX + 1]; + string procFdPath = PROC_SELF_FD + to_string(eventFd); + ssize_t pathLen = readlink(procFdPath.c_str(), eventFilePath, sizeof(eventFilePath) - 1); + if (pathLen == -1 || pathLen > PATH_MAX) { + LOGI("readlink failed , errno: %{public}d", errno); + return ""; + } + eventFilePath[pathLen] = '\0'; + + string filePath(eventFilePath); + if (!fileName.empty() && fileName.compare(".") != 0) { + filePath += "/" + fileName; + } + return filePath; +} + +void DiskUtils::CloseFd(int &fd) +{ + if (fd != -1) { + close(fd); + fd = -1; + } +} + +void DiskUtils::CloseDir(DIR *&dir) +{ + if (dir != nullptr) { + closedir(dir); + dir = nullptr; + } +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/services/clouddiskservice/seccomp_policy/BUILD.gn b/services/clouddiskservice/seccomp_policy/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b1b3bef58b0e6941ba5dd98e05021a05264d2eea --- /dev/null +++ b/services/clouddiskservice/seccomp_policy/BUILD.gn @@ -0,0 +1,28 @@ +# 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. + +import("//build/config/components/init/seccomp/scripts/seccomp_policy_fixer.gni") + +ohos_prebuilt_seccomp("disk_monitor_seccomp_filter") { + sources = [ "clouddiskservice.seccomp.policy" ] + + filtername = "clouddiskservice" + + process_type = "system" + + part_name = "dfs_service" + subsystem_name = "filemanagement" + + install_enable = true + install_images = [ "system" ] +} \ No newline at end of file diff --git a/services/clouddiskservice/seccomp_policy/clouddiskservice.seccomp.policy b/services/clouddiskservice/seccomp_policy/clouddiskservice.seccomp.policy new file mode 100644 index 0000000000000000000000000000000000000000..ccb4fe499c2b6dae15469489dd18fb1ca350ed26 --- /dev/null +++ b/services/clouddiskservice/seccomp_policy/clouddiskservice.seccomp.policy @@ -0,0 +1,341 @@ +# 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. + +# For now, it supports architechture of ['arm', 'arm64', 'riscv64']. + +@returnValue +TRAP + +@allowList +io_setup;all +io_destroy;all +io_submit;all +io_cancel;all +io_getevents;all +setxattr;all +lsetxattr;all +fsetxattr;all +getxattr;all +lgetxattr;all +fgetxattr;all +listxattr;all +llistxattr;all +flistxattr;all +removexattr;all +lremovexattr;all +fremovexattr;all +getcwd;all +eventfd2;all +epoll_create1;all +epoll_ctl;all +epoll_pwait;all +dup;all +dup3;all +fcntl;arm64 +inotify_init1;all +inotify_add_watch;all +inotify_rm_watch;all +ioctl;all +ioprio_set;arm64 +ioprio_get;arm64 +flock;all +mknodat;all +mkdirat;all +unlinkat;all +symlinkat;all +linkat;all +renameat;arm +renameat;arm64 +umount2;all +mount;all +pivot_root;all +statfs;arm64 +fstatfs;arm64 +truncate;all +ftruncate;arm64 +fallocate;all +faccessat;all +faccessat2;all +chdir;all +fchdir;all +chroot;all +fchmod;all +fchmodat;all +fchownat;all +fchown;arm64 +openat;all +close;all +pipe2;all +quotactl;all +getdents64;all +lseek;all +read;all +write;all +readv;all +writev;all +pread64;all +pwrite64;all +preadv;all +pwritev;all +sendfile;all +pselect6;all +ppoll;all +signalfd4;all +vmsplice;all +splice;all +tee;all +readlinkat;all +newfstatat;arm64 +fstat;arm64 +sync;all +fsync;all +fdatasync;all +sync_file_range;arm64 +timerfd_create;all +timerfd_settime;all +timerfd_gettime;all +utimensat;all +acct;all +capget;all +capset;all +personality;all +exit;all +exit_group;all +waitid;all +set_tid_address;all +unshare;all +futex;all +set_robust_list;all +get_robust_list;all +nanosleep;all +getitimer;all +setitimer;all +init_module;all +delete_module;all +timer_create;all +timer_gettime;all +timer_getoverrun;all +timer_settime;all +timer_delete;all +clock_settime;all +clock_gettime;all +clock_getres;all +clock_nanosleep;all +syslog;all +ptrace;all +sched_setparam;all +sched_setscheduler;all +sched_getscheduler;all +sched_getparam;all +sched_setaffinity;all +sched_getaffinity;all +sched_yield;all +sched_get_priority_max;all +sched_get_priority_min;all +sched_rr_get_interval;all +restart_syscall;all +kill;all +tkill;all +tgkill;all +sigaltstack;all +rt_sigsuspend;all +rt_sigaction;all +rt_sigprocmask;all +rt_sigpending;all +rt_sigtimedwait;all +rt_sigqueueinfo;all +rt_sigreturn;all +setpriority;all +getpriority;all +reboot;all +setregid;arm64 +setgid;arm64 +setreuid;arm64 +setuid;arm64 +setresuid;arm64 +getresuid;arm64 +setresgid;arm64 +getresgid;arm64 +setfsuid;all +setfsgid;all +times;all +setpgid;all +getpgid;all +getsid;all +setsid;all +getgroups;arm64 +setgroups;arm64 +uname;all +sethostname;all +setdomainname;all +getrlimit;arm64 +setrlimit;all +getrusage;all +umask;all +prctl;all +getcpu;all +gettimeofday;all +settimeofday;all +adjtimex;all +getpid;all +getppid;all +getuid;arm64 +geteuid;arm64 +getgid;arm64 +getegid;arm64 +gettid;all +sysinfo;all +semget;all +shmget;all +shmctl;all +shmat;all +shmdt;all +socket;all +socketpair;all +bind;all +listen;all +accept;all +connect;all +getsockname;all +getpeername;all +sendto;all +recvfrom;all +setsockopt;all +getsockopt;all +shutdown;all +sendmsg;all +recvmsg;all +readahead;all +brk;all +munmap;all +mremap;all +add_key;all +keyctl;all +clone;all +execve;all +mmap;arm64 +fadvise64;arm64 +mprotect;all +msync;all +mlock;all +munlock;all +mlockall;all +munlockall;all +mincore;all +madvise;all +rt_tgsigqueueinfo;all +perf_event_open;all +accept4;all +recvmmsg;all +wait4;all +prlimit64;all +clock_adjtime;all +syncfs;all +setns;all +sendmmsg;all +process_vm_readv;all +process_vm_writev;all +finit_module;all +sched_setattr;all +sched_getattr;all +renameat2;all +seccomp;all +getrandom;all +memfd_create;all +bpf;all +execveat;all +userfaultfd;all +membarrier;all +mlock2;all +copy_file_range;all +preadv2;all +pwritev2;all +statx;all +pidfd_send_signal;all +pidfd_open;all +close_range;all +pidfd_getfd;all +process_madvise;all +fork;arm +open;arm +unlink;arm +mknod;arm +chmod;arm +access;arm +rename;arm +mkdir;arm +rmdir;arm +pipe;arm +dup2;arm +sigaction;arm +symlink;arm +readlink;arm +stat;arm +sigreturn;arm +_llseek;arm +_newselect;arm +poll;arm +vfork;arm +ugetrlimit;arm +mmap2;arm +truncate64;arm +ftruncate64;arm +stat64;arm +fstat64;arm +lchown32;arm +getuid32;arm +getgid32;arm +geteuid32;arm +getegid32;arm +setreuid32;arm +setregid32;arm +chown32;arm +getgroups32;arm +setgroups32;arm +fchown32;arm +setresuid32;arm +getresuid32;arm +setresgid32;arm +getresgid32;arm +setuid32;arm +setgid32;arm +fcntl64;arm +sendfile64;arm +statfs64;arm +fstatfs64;arm +fadvise64_64;arm +fstatat64;arm +sync_file_range2;arm +clock_gettime64;arm +clock_settime64;arm +clock_adjtime64;arm +clock_getres_time64;arm +clock_nanosleep_time64;arm +timer_gettime64;arm +timer_settime64;arm +timerfd_gettime64;arm +timerfd_settime64;arm +utimensat_time64;arm +pselect6_time64;arm +ppoll_time64;arm +recvmmsg_time64;arm +semtimedop_time64;arm +rt_sigtimedwait_time64;arm +futex_time64;arm +sched_rr_get_interval_time64;arm +cacheflush;arm +set_tls;arm +mbind;all +fanotify_init;arm64 +fanotify_mark;arm64 +open_by_handle_at;arm64 diff --git a/test/unittests/BUILD.gn b/test/unittests/BUILD.gn index 9647db0b46d3b3efae300206441933c26dc20e21..7b3499eec6b57669d054dd4d37cca56a035b5dd4 100644 --- a/test/unittests/BUILD.gn +++ b/test/unittests/BUILD.gn @@ -22,6 +22,7 @@ group("cloudsyncunittests") { "cloud_disk:cloud_disk_test", "cloud_file_kit_inner:cloud_file_kit_inner_test", "clouddisk_database:clouddisk_database_test", + "clouddiskservice:clouddisk_service_test", "cloudsync_api:cloudsync_api_test", "cloudsync_sa:cloudsync_sa_test", "services_daemon:services_daemon_test", diff --git a/test/unittests/clouddiskservice/BUILD.gn b/test/unittests/clouddiskservice/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..bb40b775a90255e4a2164f597748871681277a85 --- /dev/null +++ b/test/unittests/clouddiskservice/BUILD.gn @@ -0,0 +1,93 @@ +# 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. + +import("//build/test.gni") +import("//foundation/filemanagement/dfs_service/distributedfile.gni") + +ohos_unittest("disk_monitor_test") { + module_out_path = "dfs_service/dfs_service" + + sources = [ + "${distributedfile_path}/test/unittests/clouddiskservice/mock/system_function_mock.cpp", + "${distributedfile_path}/test/unittests/clouddiskservice/monitor/mock_monitor/disk_utils_mock.cpp", + "${services_path}/clouddiskservice/monitor/src/disk_monitor.cpp", + "${utils_path}/log/src/utils_log.cpp", + "monitor/disk_monitor_test.cpp", + ] + + include_dirs = [ + "${distributedfile_path}/test/unittests/clouddiskservice/mock", + "${distributedfile_path}/test/unittests/clouddiskservice/monitor/mock_monitor", + "${services_path}/clouddiskservice/monitor/include", + "${utils_path}/log/include", + ] + + deps = [] + + external_deps = [ + "c_utils:utils", + "ffrt:libffrt", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + ] + + defines = [ + "private=public", + "LOG_DOMAIN=0xD003900", + "LOG_TAG=\"CloudDiskService\"", + ] + + use_exceptions = true +} + +ohos_unittest("disk_utils_test") { + module_out_path = "dfs_service/dfs_service" + + sources = [ + "${distributedfile_path}/test/unittests/clouddiskservice/monitor/mock_utils/system_function_mock.cpp", + "${services_path}/clouddiskservice/monitor/src/disk_utils.cpp", + "${utils_path}/log/src/utils_log.cpp", + "monitor/disk_utils_test.cpp" + ] + + include_dirs = [ + "${distributedfile_path}/test/unittests/clouddiskservice/mock", + "${services_path}/clouddiskservice/monitor/include", + "${utils_path}/log/include", + ] + + deps = [] + + external_deps = [ + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + ] + + defines = [ + "private=public", + "LOG_DOMAIN=0xD003900", + "LOG_TAG=\"CloudDiskService\"", + ] + + use_exceptions = true +} + +group("clouddisk_service_test") { + testonly = true + deps = [ + ":disk_monitor_test", + ":disk_utils_test", + ] +} \ No newline at end of file diff --git a/test/unittests/clouddiskservice/mock/assistant.h b/test/unittests/clouddiskservice/mock/assistant.h new file mode 100644 index 0000000000000000000000000000000000000000..6280dd319ba94499c54edcbed768e12b3b1b0d5c --- /dev/null +++ b/test/unittests/clouddiskservice/mock/assistant.h @@ -0,0 +1,45 @@ +/* + * 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 TEST_UNITTEST_CLOUD_DISK_SERVICE_ASSISTANT_H +#define TEST_UNITTEST_CLOUD_DISK_SERVICE_ASSISTANT_H + +#include +#include + +namespace OHOS::FileManagement::CloudDiskService { +class Assistant { +public: + static inline std::shared_ptr ins = nullptr; + + virtual ~Assistant() = default; + virtual ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) = 0; + virtual int fanotify_init(unsigned flags, unsigned event_f_flags) = 0; + virtual int fanotify_mark(int fanotify_fd, unsigned flags, unsigned long long mask, int dfd, + const char *pathname) = 0; + virtual DIR *opendir(const char *path) = 0; + virtual int dirfd(DIR *d) = 0; +}; + +class AssistantMock : public Assistant { +public: + MOCK_METHOD3(readlink, ssize_t(const char *, char *, size_t)); + MOCK_METHOD2(fanotify_init, int(unsigned, unsigned)); + MOCK_METHOD5(fanotify_mark, int(int, unsigned, unsigned long long, int, const char *)); + MOCK_METHOD1(opendir, DIR *(const char *)); + MOCK_METHOD1(dirfd, int(DIR *)); +}; +} // namespace OHOS::FileManagement::CloudDiskService + +#endif // TEST_UNITTEST_CLOUD_DISK_SERVICE_ASSISTANT_H diff --git a/test/unittests/clouddiskservice/mock/system_function_mock.cpp b/test/unittests/clouddiskservice/mock/system_function_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b10d5a4608f42618cd4eae6fd49aa5ee6f410c89 --- /dev/null +++ b/test/unittests/clouddiskservice/mock/system_function_mock.cpp @@ -0,0 +1,47 @@ +/* + * 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 "assistant.h" +#include + +using namespace OHOS::FileManagement::CloudDiskService; + +ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) +{ + return Assistant::ins->readlink(pathname, buf, bufsiz); +} + +int fanotify_init(unsigned flags, unsigned event_f_flags) +{ + return Assistant::ins->fanotify_init(flags, event_f_flags); +} + +int fanotify_mark(int fanotify_fd, + unsigned flags, + unsigned long long mask, + int dfd, + const char *pathname) +{ + return Assistant::ins->fanotify_mark(fanotify_fd, flags, mask, dfd, pathname); +} + +DIR* opendir(const char* path) +{ + return Assistant::ins->opendir(path); +} + +int dirfd(DIR *d) +{ + return Assistant::ins->dirfd(d); +} diff --git a/test/unittests/clouddiskservice/monitor/disk_monitor_test.cpp b/test/unittests/clouddiskservice/monitor/disk_monitor_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f17395bead34a745c5647fa0dcb24d9b40a76592 --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/disk_monitor_test.cpp @@ -0,0 +1,851 @@ +/* + * 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 "disk_monitor.h" + +#include +#include + +#include "assistant.h" +#include "cloud_disk_sync_folder.h" + +namespace OHOS::FileManagement::CloudDiskService::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +namespace { +constexpr int32_t INVALID_SYNC_FOLDER = 0; +const string MOUNT_PATH = "/data/service"; +const string DATA_SERVICE_EL2 = "/data/service/el2/"; +const string HMDFS_DOCS = "/hmdfs/account/files/Docs"; +const vector BLACK_DIRS = {"/.Trash", "/.Recent", "/.thumbs", "/HO_DATA_EXT_MISC"}; +} // namespace + +class DiskMonitorTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr insMock_; + int32_t userId = 100; +}; + +void DiskMonitorTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + insMock_ = make_shared(); + Assistant::ins = insMock_; +} + +void DiskMonitorTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + Assistant::ins = nullptr; + insMock_ = nullptr; +} + +void DiskMonitorTest::SetUp(void) {} + +void DiskMonitorTest::TearDown(void) {} + +/** +@tc.name: GetInstanceTest001 +@tc.desc: Verify the GetInstance function returns singleton instance +@tc.type: FUNC +*/ +HWTEST_F(DiskMonitorTest, GetInstanceTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetInstanceTest001 Begin"; + try { + DiskMonitor::GetInstance(); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetInstanceTest001 Error"; + } + GTEST_LOG_(INFO) << "GetInstanceTest001 End"; +} + +/** + * @tc.name: StartMonitorTest001 + * @tc.desc: Verify StartMonitor function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, StartMonitorTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StartMonitorTest001 Begin"; + try { + int32_t userId = 1; + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(-1)); + DiskMonitor::GetInstance().isRunning_ = false; + bool res = DiskMonitor::GetInstance().StartMonitor(userId); + DiskMonitor::GetInstance().StopMonitor(); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "StartMonitorTest001 Error"; + } + GTEST_LOG_(INFO) << "StartMonitorTest001 End"; +} + +/** + * @tc.name: StartMonitorTest002 + * @tc.desc: Verify StartMonitor function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, StartMonitorTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StartMonitorTest002 Begin"; + try { + int32_t userId = 1; + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*insMock_, fanotify_mark(_, _, _, _, _)).WillOnce(Return(0)); + DIR *ch = reinterpret_cast(UINT64_MAX); + EXPECT_CALL(*insMock_, opendir(_)).WillOnce(Return(ch)); + EXPECT_CALL(*insMock_, dirfd(_)).WillOnce(Return(0)); + + bool res = DiskMonitor::GetInstance().StartMonitor(userId); + DiskMonitor::GetInstance().StopMonitor(); + EXPECT_TRUE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "StartMonitorTest002 Error"; + } + GTEST_LOG_(INFO) << "StartMonitorTest002 End"; +} + +/** + * @tc.name: StopMonitorTest001 + * @tc.desc: Verify StopMonitor function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, StopMonitorTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StopMonitorTest001 Begin"; + try { + DiskMonitor::GetInstance().StopMonitor(); + EXPECT_EQ(DiskMonitor::GetInstance().userId_, -1); + EXPECT_EQ(DiskMonitor::GetInstance().isRunning_, false); + EXPECT_TRUE(DiskMonitor::GetInstance().syncFolderPrefix_.empty()); + EXPECT_TRUE(DiskMonitor::GetInstance().blockList_.empty()); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "StopMonitorTest001 Error"; + } + GTEST_LOG_(INFO) << "StopMonitorTest001 End"; +} + +/** + * @tc.name: InitStatusTest001 + * @tc.desc: Verify InitStatus function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, InitStatusTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InitStatusTest001 Begin"; + try { + int32_t userId = 1; + DiskMonitor::GetInstance().InitStatus(userId); + + EXPECT_EQ(DiskMonitor::GetInstance().userId_, userId); + EXPECT_TRUE(DiskMonitor::GetInstance().isRunning_); + EXPECT_EQ(DiskMonitor::GetInstance().syncFolderPrefix_, "/data/service/el2/1/hmdfs/account/files/Docs"); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InitStatusTest001 Error"; + } + GTEST_LOG_(INFO) << "InitStatusTest001 End"; +} + +/** + * @tc.name: InitFanotifyTest001 + * @tc.desc: Verify InitFanotify function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, InitFanotifyTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InitFanotifyTest001 Begin"; + try { + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(-1)); + bool res = DiskMonitor::GetInstance().InitFanotify(); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InitFanotifyTest001 Error"; + } + GTEST_LOG_(INFO) << "InitFanotifyTest001 End"; +} + +/** + * @tc.name: InitFanotifyTest002 + * @tc.desc: Verify InitFanotify function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, InitFanotifyTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InitFanotifyTest002 Begin"; + try { + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*insMock_, fanotify_mark(_, _, _, _, _)).WillOnce(Return(-1)); + bool res = DiskMonitor::GetInstance().InitFanotify(); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InitFanotifyTest002 Error"; + } + GTEST_LOG_(INFO) << "InitFanotifyTest002 End"; +} + +/** + * @tc.name: InitFanotifyTest003 + * @tc.desc: Verify InitFanotify function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, InitFanotifyTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InitFanotifyTest003 Begin"; + try { + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*insMock_, fanotify_mark(_, _, _, _, _)).WillOnce(Return(0)); + EXPECT_CALL(*insMock_, opendir(_)).WillOnce(Return(nullptr)); + bool res = DiskMonitor::GetInstance().InitFanotify(); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InitFanotifyTest003 Error"; + } + GTEST_LOG_(INFO) << "InitFanotifyTest003 End"; +} + +/** + * @tc.name: InitFanotifyTest004 + * @tc.desc: Verify InitFanotify function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, InitFanotifyTest004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InitFanotifyTest004 Begin"; + try { + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*insMock_, fanotify_mark(_, _, _, _, _)).WillOnce(Return(0)); + DIR *ch = reinterpret_cast(UINT64_MAX); + EXPECT_CALL(*insMock_, opendir(_)).WillOnce(Return(ch)); + EXPECT_CALL(*insMock_, dirfd(_)).WillOnce(Return(-1)); + + bool res = DiskMonitor::GetInstance().InitFanotify(); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InitFanotifyTest004 Error"; + } + GTEST_LOG_(INFO) << "InitFanotifyTest004 End"; +} + +/** + * @tc.name: InitFanotifyTest005 + * @tc.desc: Verify InitFanotify function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, InitFanotifyTest005, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "InitFanotifyTest005 Begin"; + try { + EXPECT_CALL(*insMock_, fanotify_init(_, _)).WillOnce(Return(0)); + EXPECT_CALL(*insMock_, fanotify_mark(_, _, _, _, _)).WillOnce(Return(0)); + DIR *ch = reinterpret_cast(UINT64_MAX); + EXPECT_CALL(*insMock_, opendir(_)).WillOnce(Return(ch)); + EXPECT_CALL(*insMock_, dirfd(_)).WillOnce(Return(0)); + + bool res = DiskMonitor::GetInstance().InitFanotify(); + EXPECT_TRUE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "InitFanotifyTest005 Error"; + } + GTEST_LOG_(INFO) << "InitFanotifyTest005 End"; +} + +/** + * @tc.name: EventProcessTest001 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest001 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_CREATE; + string filePath = "filePath"; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest001 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest001 End"; +} + +/** + * @tc.name: EventProcessTest002 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest002 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_DELETE; + string filePath = "filePath"; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest002 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest002 End"; +} + +/** + * @tc.name: EventProcessTest003 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest003 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_MOVED_FROM; + string filePath = "filePath"; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest003 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest003 End"; +} + +/** + * @tc.name: EventProcessTest004 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest004 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_MOVED_TO; + string filePath = "filePath"; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest004 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest004 End"; +} + +/** + * @tc.name: EventProcessTest005 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest005, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest005 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_CLOSE_WRITE; + string filePath = "filePath"; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest005 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest005 End"; +} + +/** + * @tc.name: EventProcessTest006 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest006, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest006 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_CLOSE_WRITE; + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string filePath = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest006 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest006 End"; +} + +/** + * @tc.name: EventProcessTest007 + * @tc.desc: Verify EventProcess function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, EventProcessTest007, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "EventProcessTest006 Begin"; + try { + fanotify_event_metadata metaData; + metaData.mask = FAN_ONDIR; + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string filePath = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + DiskMonitor::GetInstance().EventProcess(&metaData, filePath); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "EventProcessTest007 Error"; + } + GTEST_LOG_(INFO) << "EventProcessTest007 End"; +} + +/** + * @tc.name: HandleCreateTest001 + * @tc.desc: Verify HandleCreate function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleCreateTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCreateTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + DiskMonitor::GetInstance().HandleCreate(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCreateTest001 Error"; + } + GTEST_LOG_(INFO) << "HandleCreateTest001 End"; +} + +/** + * @tc.name: HandleCreateTest002 + * @tc.desc: Verify HandleCreate function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleCreateTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCreateTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().HandleCreate(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCreateTest002 Error"; + } + GTEST_LOG_(INFO) << "HandleCreateTest002 End"; +} + +/** + * @tc.name: HandleDeleteTest001 + * @tc.desc: Verify HandleDelete function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleDeleteTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleDeleteTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + DiskMonitor::GetInstance().HandleDelete(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleDeleteTest001 Error"; + } + GTEST_LOG_(INFO) << "HandleDeleteTest001 End"; +} + +/** + * @tc.name: HandleDeleteTest002 + * @tc.desc: Verify HandleDelete function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleDeleteTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleDeleteTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().HandleDelete(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleDeleteTest002 Error"; + } + GTEST_LOG_(INFO) << "HandleDeleteTest002 End"; +} + +/** + * @tc.name: HandleMoveFromTest001 + * @tc.desc: Verify HandleMoveFrom function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveFromTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveFromTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + DiskMonitor::GetInstance().HandleMoveFrom(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveFromTest001 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveFromTest001 End"; +} + +/** + * @tc.name: HandleMoveFromTest002 + * @tc.desc: Verify HandleMoveFrom function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveFromTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveFromTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().HandleMoveFrom(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveFromTest002 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveFromTest002 End"; +} + +/** + * @tc.name: HandleMoveToTest001 + * @tc.desc: Verify HandleMoveTo function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveToTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveToTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + DiskMonitor::GetInstance().oldEventInfo_.syncFolderIndex = INVALID_SYNC_FOLDER; + DiskMonitor::GetInstance().HandleMoveTo(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveToTest001 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveToTest001 End"; +} + +/** + * @tc.name: HandleMoveToTest002 + * @tc.desc: Verify HandleMoveTo function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveToTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveToTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().oldEventInfo_.syncFolderIndex = INVALID_SYNC_FOLDER; + DiskMonitor::GetInstance().HandleMoveTo(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveToTest002 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveToTest002 End"; +} + +/** + * @tc.name: HandleMoveToTest003 + * @tc.desc: Verify HandleMoveTo function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveToTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveToTest003 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + DiskMonitor::GetInstance().oldEventInfo_.syncFolderIndex = 1; + DiskMonitor::GetInstance().HandleMoveTo(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveToTest003 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveToTest003 End"; +} + +/** + * @tc.name: HandleMoveToTest004 + * @tc.desc: Verify HandleMoveTo function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveToTest004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveToTest004 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().oldEventInfo_.syncFolderIndex = 1; + DiskMonitor::GetInstance().HandleMoveTo(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveToTest004 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveToTest004 End"; +} + +/** + * @tc.name: HandleMoveToTest005 + * @tc.desc: Verify HandleMoveTo function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleMoveToTest005, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleMoveToTest005 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({2, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().oldEventInfo_.syncFolderIndex = 1; + DiskMonitor::GetInstance().HandleMoveTo(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleMoveToTest005 Error"; + } + GTEST_LOG_(INFO) << "HandleMoveToTest005 End"; +} + +/** + * @tc.name: HandleCloseWriteTest001 + * @tc.desc: Verify HandleCloseWrite function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleCloseWriteTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCloseWriteTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + DiskMonitor::GetInstance().HandleCloseWrite(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCloseWriteTest001 Error"; + } + GTEST_LOG_(INFO) << "HandleCloseWriteTest001 End"; +} + +/** + * @tc.name: HandleCloseWriteTest002 + * @tc.desc: Verify HandleCloseWrite function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, HandleCloseWriteTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "HandleCloseWriteTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + DiskMonitor::GetInstance().HandleCloseWrite(path); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "HandleCloseWriteTest002 Error"; + } + GTEST_LOG_(INFO) << "HandleCloseWriteTest002 End"; +} + +/** + * @tc.name: IsInBlockListTest001 + * @tc.desc: Verify the IsInBlockList function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, IsInBlockListTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IsInBlockListTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + bool res = DiskMonitor::GetInstance().IsInBlockList(path); + EXPECT_TRUE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IsInBlockListTest001 Error"; + } + GTEST_LOG_(INFO) << "IsInBlockListTest001 End"; +} + +/** + * @tc.name: IsInBlockListTest002 + * @tc.desc: Verify the IsInBlockList function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, IsInBlockListTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IsInBlockListTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"a", "b"}; + bool res = DiskMonitor::GetInstance().IsInBlockList(path); + EXPECT_TRUE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IsInBlockListTest002 Error"; + } + GTEST_LOG_(INFO) << "IsInBlockListTest002 End"; +} + +/** + * @tc.name: IsInBlockListTest003 + * @tc.desc: Verify the IsInBlockList function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, IsInBlockListTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IsInBlockListTest003 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + bool res = DiskMonitor::GetInstance().IsInBlockList(path); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IsInBlockListTest003 Error"; + } + GTEST_LOG_(INFO) << "IsInBlockListTest003 End"; +} + +/** + * @tc.name: GetSyncFolderIndexTest001 + * @tc.desc: Verify the GetSyncFolderIndex function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, GetSyncFolderIndexTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest001 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "b"; + string path = "abc"; + pair res = DiskMonitor::GetInstance().GetSyncFolderIndex(path); + EXPECT_EQ(res.first, INVALID_SYNC_FOLDER); + EXPECT_FALSE(res.second); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest001 Error"; + } + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest001 End"; +} + +/** + * @tc.name: GetSyncFolderIndexTest002 + * @tc.desc: Verify the GetSyncFolderIndex function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, GetSyncFolderIndexTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest002 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc/d"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + pair res = DiskMonitor::GetInstance().GetSyncFolderIndex(path); + EXPECT_EQ(res.first, 1); + EXPECT_FALSE(res.second); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest002 Error"; + } + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest002 End"; +} + +/** + * @tc.name: GetSyncFolderIndexTest003 + * @tc.desc: Verify the GetSyncFolderIndex function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, GetSyncFolderIndexTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest003 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "abc"}}); + pair res = DiskMonitor::GetInstance().GetSyncFolderIndex(path); + EXPECT_EQ(res.first, 1); + EXPECT_TRUE(res.second); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest003 Error"; + } + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest003 End"; +} + +/** + * @tc.name: GetSyncFolderIndexTest004 + * @tc.desc: Verify the GetSyncFolderIndex function + * @tc.type: FUNC + */ +HWTEST_F(DiskMonitorTest, GetSyncFolderIndexTest004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest004 Begin"; + try { + DiskMonitor::GetInstance().syncFolderPrefix_ = "a"; + string path = "abc"; + DiskMonitor::GetInstance().blockList_ = {"b", "c"}; + CloudDiskSyncFolder::GetInstance().syncFolderMap.clear(); + CloudDiskSyncFolder::GetInstance().syncFolderMap.insert({1, {"bundleName", "b"}}); + pair res = DiskMonitor::GetInstance().GetSyncFolderIndex(path); + EXPECT_EQ(res.first, INVALID_SYNC_FOLDER); + EXPECT_FALSE(res.second); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest004 Error"; + } + GTEST_LOG_(INFO) << "GetSyncFolderIndexTest004 End"; +} +} // namespace OHOS::FileManagement::CloudDiskService::Test diff --git a/test/unittests/clouddiskservice/monitor/disk_utils_test.cpp b/test/unittests/clouddiskservice/monitor/disk_utils_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53cdf73524e87a0ce8d630b09e40df35e9d31259 --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/disk_utils_test.cpp @@ -0,0 +1,335 @@ +/* + * 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 "disk_utils.h" + +#include +#include + +#include "assistant.h" + +namespace OHOS::FileManagement::CloudDiskService::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class DiskUtilsTest : public testing::Test { +#define FAN_EVENT_INFO_TYPE_FID 1 +#define FAN_EVENT_INFO_TYPE_DFID_NAME 2 +#define FAN_EVENT_INFO_TYPE_DFID 3 +#define PATH_MAX 4096 +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr diskUtils_; + static inline shared_ptr insMock_; +}; + +void DiskUtilsTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + diskUtils_ = make_shared(); + insMock_ = make_shared(); + Assistant::ins = insMock_; +} + +void DiskUtilsTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + diskUtils_ = nullptr; + Assistant::ins = nullptr; + insMock_ = nullptr; +} + +void DiskUtilsTest::SetUp(void) {} + +void DiskUtilsTest::TearDown(void) {} + +/** + * @tc.name: IExtractFileNameTest001 + * @tc.desc: Verify the ExtractFileName function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, IExtractFileNameTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IExtractFileNameTest001 Begin"; + try { + int type = FAN_EVENT_INFO_TYPE_FID; + string fileName = "fileName"; + struct file_handle file_handle_test; + bool res = diskUtils_->ExtractFileName(type, fileName, &file_handle_test); + EXPECT_TRUE(res); + EXPECT_EQ(fileName, ""); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IExtractFileNameTest001 Error"; + } + GTEST_LOG_(INFO) << "IExtractFileNameTest001 End"; +} + +/** + * @tc.name: IExtractFileNameTest002 + * @tc.desc: Verify the ExtractFileName function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, IExtractFileNameTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IExtractFileNameTest002 Begin"; + try { + int type = FAN_EVENT_INFO_TYPE_DFID_NAME; + string fileName = "fileName"; + struct file_handle file_handle_test; + file_handle_test.handle_bytes = 1; + bool res = diskUtils_->ExtractFileName(type, fileName, &file_handle_test); + EXPECT_TRUE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IExtractFileNameTest002 Error"; + } + GTEST_LOG_(INFO) << "IExtractFileNameTest002 End"; +} + +/** + * @tc.name: IExtractFileNameTest003 + * @tc.desc: Verify the ExtractFileName function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, IExtractFileNameTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IExtractFileNameTest003 Begin"; + try { + int type = 4; + string fileName = "fileName"; + struct file_handle file_handle_test; + bool res = diskUtils_->ExtractFileName(type, fileName, &file_handle_test); + EXPECT_FALSE(res); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IExtractFileNameTest003 Error"; + } + GTEST_LOG_(INFO) << "IExtractFileNameTest003 End"; +} + +/** + * @tc.name: IExtractFileNameTest004 + * @tc.desc: Verify the ExtractFileName function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, IExtractFileNameTest004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "IExtractFileNameTest004 Begin"; + try { + int type = FAN_EVENT_INFO_TYPE_DFID; + string fileName = "fileName"; + struct file_handle file_handle_test; + bool res = diskUtils_->ExtractFileName(type, fileName, &file_handle_test); + EXPECT_TRUE(res); + EXPECT_EQ(fileName, ""); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "IExtractFileNameTest004 Error"; + } + GTEST_LOG_(INFO) << "IExtractFileNameTest004 End"; +} + +/** + * @tc.name: CloseFdTest001 + * @tc.desc: Verify the CloseFd function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, CloseFdTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CloseFdTest001 Begin"; + try { + int fd = 0; + diskUtils_->CloseFd(fd); + EXPECT_EQ(fd, -1); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "CloseFdTest001 Error"; + } + GTEST_LOG_(INFO) << "CloseFdTest001 End"; +} + +/** + * @tc.name: CloseFdTest002 + * @tc.desc: Verify the CloseFd function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, CloseFdTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CloseFdTest002 Begin"; + try { + int fd = -1; + diskUtils_->CloseFd(fd); + EXPECT_EQ(fd, -1); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "CloseFdTest002 Error"; + } + GTEST_LOG_(INFO) << "CloseFdTest002 End"; +} + +/** + * @tc.name: CloseDirTest001 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, CloseDirTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CloseDirTest001 Begin"; + try { + DIR *dir = opendir("/data"); + diskUtils_->CloseDir(dir); + EXPECT_EQ(dir, nullptr); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "CloseDirTest001 Error"; + } + GTEST_LOG_(INFO) << "CloseDirTest001 End"; +} + +/** + * @tc.name: CloseDirTest002 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, CloseDirTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CloseDirTest002 Begin"; + try { + DIR *dir = nullptr; + diskUtils_->CloseDir(dir); + EXPECT_EQ(dir, nullptr); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "CloseDirTest002 Error"; + } + GTEST_LOG_(INFO) << "CloseDirTest002 End"; +} + +/** + * @tc.name: GetFilePathTest001 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, GetFilePathTest001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetFilePathTest001 Begin"; + try { + int32_t eventFd = 1; + string fileName = "fileName"; + EXPECT_CALL(*insMock_, readlink(_, _, _)).WillOnce(Return(-1)); + string res = diskUtils_->GetFilePath(eventFd, fileName); + EXPECT_EQ(res, ""); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetFilePathTest001 Error"; + } + GTEST_LOG_(INFO) << "GetFilePathTest001 End"; +} + +/** + * @tc.name: GetFilePathTest002 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, GetFilePathTest002, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetFilePathTest002 Begin"; + try { + int32_t eventFd = 1; + string fileName = "fileName"; + EXPECT_CALL(*insMock_, readlink(_, _, _)).WillOnce(Return(PATH_MAX + 1)); + string res = diskUtils_->GetFilePath(eventFd, fileName); + EXPECT_EQ(res, ""); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetFilePathTest002 Error"; + } + GTEST_LOG_(INFO) << "GetFilePathTest002 End"; +} + +/** + * @tc.name: GetFilePathTest003 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, GetFilePathTest003, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetFilePathTest003 Begin"; + try { + int32_t eventFd = 1; + string fileName = "fileName"; + char path[] = "/path"; + EXPECT_CALL(*insMock_, readlink(_, _, _)) + .WillOnce(DoAll(SetArrayArgument<1>(path, path + sizeof(path) - 1), Return(5))); + string res = diskUtils_->GetFilePath(eventFd, fileName); + EXPECT_EQ(res, "/path/fileName"); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetFilePathTest003 Error"; + } + GTEST_LOG_(INFO) << "GetFilePathTest003 End"; +} + +/** + * @tc.name: GetFilePathTest004 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, GetFilePathTest004, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetFilePathTest004 Begin"; + try { + int32_t eventFd = 1; + string fileName = ""; + char path[] = "/path"; + EXPECT_CALL(*insMock_, readlink(_, _, _)) + .WillOnce(DoAll(SetArrayArgument<1>(path, path + sizeof(path) - 1), Return(5))); + string res = diskUtils_->GetFilePath(eventFd, fileName); + EXPECT_EQ(res, "/path"); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetFilePathTest004 Error"; + } + GTEST_LOG_(INFO) << "GetFilePathTest004 End"; +} + +/** + * @tc.name: GetFilePathTest005 + * @tc.desc: Verify the CloseDir function + * @tc.type: FUNC + */ +HWTEST_F(DiskUtilsTest, GetFilePathTest005, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "GetFilePathTest005 Begin"; + try { + int32_t eventFd = 1; + string fileName = "."; + char path[] = "/path"; + EXPECT_CALL(*insMock_, readlink(_, _, _)) + .WillOnce(DoAll(SetArrayArgument<1>(path, path + sizeof(path) - 1), Return(5))); + string res = diskUtils_->GetFilePath(eventFd, fileName); + EXPECT_EQ(res, "/path"); + } catch (...) { + EXPECT_TRUE(false); + GTEST_LOG_(INFO) << "GetFilePathTest005 Error"; + } + GTEST_LOG_(INFO) << "GetFilePathTest005 End"; +} +} // namespace OHOS::FileManagement::CloudDiskService::Test \ No newline at end of file diff --git a/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_common.h b/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_common.h new file mode 100644 index 0000000000000000000000000000000000000000..1aed8391485a51ffcf315ee84a996e59713cac00 --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_common.h @@ -0,0 +1,34 @@ +/* + * 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_FILEMGMT_CLOUD_DISK_COMMON_H +#define OHOS_FILEMGMT_CLOUD_DISK_COMMON_H + +namespace OHOS::FileManagement::CloudDiskService { +/* + * for tdd only, do not depend other modules + */ +enum class OperationType : uint8_t { + NONE = 0, + CREATE, + DELETE, + MOVE_FROM, + MOVE_TO, + CLOSE_WRITE, + SYNC_FOLDER_INVALID, + OPERATION_MAX, +}; +} // namespace OHOS::FileManagement::CloudDiskService +#endif // OHOS_FILEMGMT_CLOUD_DISK_COMMON_H \ No newline at end of file diff --git a/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_service_syncfolder.h b/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_service_syncfolder.h new file mode 100644 index 0000000000000000000000000000000000000000..bc3c55d84ef2abb01ae8cf847c2d1a868f1dbd02 --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_service_syncfolder.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 CLOUD_DISK_SERVICE_SYNCFOLDER_H +#define CLOUD_DISK_SERVICE_SYNCFOLDER_H + +#include "disk_types.h" + +namespace OHOS { +namespace FileManagement { +namespace CloudDiskService { +/* + * for tdd only, do not depend other modules + */ +class CloudDiskServiceSyncFolder { +public: + static int32_t SetSyncFolderChanges(const struct EventInfo &eventInfos) + { + return 0; + } +}; +} // namespace CloudDiskService +} // namespace FileManagement +} // namespace OHOS +#endif \ No newline at end of file diff --git a/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_sync_folder.h b/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_sync_folder.h new file mode 100644 index 0000000000000000000000000000000000000000..0b88a3b62d490ae24ae20a479b9d8e5095ec3f43 --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/mock_monitor/cloud_disk_sync_folder.h @@ -0,0 +1,53 @@ +/* + * 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 CLOUD_DISK_SYNC_FOLDER_H +#define CLOUD_DISK_SYNC_FOLDER_H + +#include +#include + +namespace OHOS { +namespace FileManagement { +namespace CloudDiskService { + +struct SyncFolderValue { + std::string bundleName; + std::string path; +}; + +/* + * for tdd only, do not depend other modules + */ +class CloudDiskSyncFolder { +public: + static CloudDiskSyncFolder &GetInstance() + { + static CloudDiskSyncFolder instance; + return instance; + } + + std::unordered_map GetSyncFolderMap() + { + return syncFolderMap; + } + +private: + std::unordered_map syncFolderMap; +}; +} // namespace CloudDiskService +} // namespace FileManagement +} // namespace OHOS +#endif // CLOUD_DISK_SYNC_FOLDER_H diff --git a/test/unittests/clouddiskservice/monitor/mock_monitor/disk_utils_mock.cpp b/test/unittests/clouddiskservice/monitor/mock_monitor/disk_utils_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..768b0b6645f1d70be90f37407c4da77c8cc29b2b --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/mock_monitor/disk_utils_mock.cpp @@ -0,0 +1,44 @@ +/* + * 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 "disk_utils.h" + +#include +#include + +#include "utils_log.h" + +namespace OHOS::FileManagement::CloudDiskService { +using namespace std; + +bool DiskUtils::ExtractFileName(int type, string &fileName, struct file_handle *fileHandle) +{ + fileName = ""; + return true; +} + +string DiskUtils::GetFilePath(int32_t eventFd, const string &fileName) +{ + return ""; +} + +void DiskUtils::CloseFd(int &fd) +{ +} + +void DiskUtils::CloseDir(DIR *&dir) +{ +} +} // namespace OHOS::FileManagement::CloudDiskService \ No newline at end of file diff --git a/test/unittests/clouddiskservice/monitor/mock_utils/system_function_mock.cpp b/test/unittests/clouddiskservice/monitor/mock_utils/system_function_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..04ecf1a92cb249c84580bdb229cddb2bcc09a9a3 --- /dev/null +++ b/test/unittests/clouddiskservice/monitor/mock_utils/system_function_mock.cpp @@ -0,0 +1,22 @@ +/* + * 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 "assistant.h" + +using namespace OHOS::FileManagement::CloudDiskService; + +ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) +{ + return Assistant::ins->readlink(pathname, buf, bufsiz); +}