From 1789cda9b4a028b6a5c0ff6867f5df2465c30e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9C=E5=B0=8F=E6=9E=97?= Date: Fri, 16 May 2025 17:32:12 +0800 Subject: [PATCH 1/9] =?UTF-8?q?copy=E6=8E=A5=E5=8F=A3bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I4958b6b4ea03d236d089391c2c755b5391f0d485 Signed-off-by: 姜小林 --- interfaces/kits/js/BUILD.gn | 6 +- .../js/src/mod_fs/ani/ets/@ohos.file.fs.ets | 15 +- .../class_tasksignal/ani/task_signal_ani.cpp | 81 ++----- .../class_tasksignal/ani/task_signal_ani.h | 8 +- .../ani/task_signal_listener_ani.cpp | 63 +++++ .../task_signal_listener_ani.h} | 41 ++-- .../ani/task_signal_wrapper.cpp | 71 ++++++ .../ani/task_signal_wrapper.h | 37 +++ .../class_tasksignal/fs_task_signal.cpp | 79 +++++++ .../mod_fs/class_tasksignal/fs_task_signal.h | 50 ++++ .../js/src/mod_fs/properties/ani/copy_ani.cpp | 159 ++++++------- .../js/src/mod_fs/properties/copy_core.cpp | 222 ++++++++---------- .../kits/js/src/mod_fs/properties/copy_core.h | 126 +++++----- .../ani/progress_listener_ani.cpp | 93 ++++++++ .../copy_listener/ani/progress_listener_ani.h | 39 +++ .../copy_listener/i_progress_listener.h} | 27 ++- .../copy_listener/trans_listener_core.cpp | 56 +++-- .../copy_listener/trans_listener_core.h | 28 +-- 18 files changed, 782 insertions(+), 419 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp rename interfaces/kits/js/src/mod_fs/class_tasksignal/{task_signal_entity_core.h => ani/task_signal_listener_ani.h} (47%) create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h create mode 100644 interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp create mode 100644 interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h rename interfaces/kits/js/src/mod_fs/{class_tasksignal/task_signal_entity_core.cpp => properties/copy_listener/i_progress_listener.h} (50%) diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 97cbc5d2f..d76e110b2 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -681,6 +681,7 @@ ohos_shared_library("ani_file_fs") { "src/mod_fs/properties", "src/mod_fs/properties/ani", "src/mod_fs/properties/copy_listener", + "src/mod_fs/properties/copy_listener/ani", ] sources = [ "src/common/ani_helper/ani_signature.cpp", @@ -709,7 +710,9 @@ ohos_shared_library("ani_file_fs") { "src/mod_fs/class_stream/fs_stream.cpp", "src/mod_fs/class_stream/stream_instantiator.cpp", "src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp", - "src/mod_fs/class_tasksignal/task_signal_entity_core.cpp", + "src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp", + "src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp", + "src/mod_fs/class_tasksignal/fs_task_signal.cpp", "src/mod_fs/class_watcher/ani/fs_watcher_ani.cpp", "src/mod_fs/class_watcher/ani/fs_watcher_wrapper.cpp", "src/mod_fs/class_watcher/ani/watch_event_listener.cpp", @@ -755,6 +758,7 @@ ohos_shared_library("ani_file_fs") { "src/mod_fs/properties/copy_core.cpp", "src/mod_fs/properties/copy_dir_core.cpp", "src/mod_fs/properties/copy_file_core.cpp", + "src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp", "src/mod_fs/properties/copy_listener/trans_listener_core.cpp", "src/mod_fs/properties/create_randomaccessfile_core.cpp", "src/mod_fs/properties/create_stream_core.cpp", diff --git a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets index 03f56f6b0..1ebce3e37 100644 --- a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets +++ b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets @@ -1263,20 +1263,29 @@ export type ProgressListener = (progress: Progress) => void; export class TaskSignal { private nativeTaskSignal: long = 0; + private native onCancelNative(): void; - private onCancelResolve: (path: string) => void = (path: string): void => {}; + + private onCancelResolve: (path: string) => void; private onCancelCallback(path: string): void { if (this.onCancelResolve) { this.onCancelResolve(path); } } + native cancel(): void; + onCancel(): Promise { - return new Promise((resolve: (path: string) => void, reject: (e: BusinessError) => void): void => { + return new Promise((resolve: (result: string) => void, reject: (e: BusinessError) => void): void => { this.onCancelResolve = resolve; - this.onCancelNative(); + try { + this.onCancelNative(); + } catch (e: BusinessError) { + reject(e); + } }); } + } export interface CopyOptions { diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp index f22a814f9..2b1229a69 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.cpp @@ -19,7 +19,8 @@ #include "copy_core.h" #include "error_handler.h" #include "filemgmt_libhilog.h" -#include "task_signal_entity_core.h" +#include "fs_task_signal.h" +#include "task_signal_wrapper.h" #include "type_converter.h" namespace OHOS { @@ -29,84 +30,40 @@ namespace ANI { using namespace std; using namespace OHOS::FileManagement::ModuleFileIO; -static TaskSignalEntityCore *Unwrap(ani_env *env, ani_object object) -{ - ani_long entity; - auto ret = env->Object_GetFieldByName_Long(object, "nativeTaskSignal", &entity); - if (ret != ANI_OK) { - HILOGE("Unwrap taskSignalEntityCore err: %{private}d", ret); - return nullptr; - } - return reinterpret_cast(entity); -} - void TaskSignalAni::Cancel(ani_env *env, [[maybe_unused]] ani_object object) { - auto entity = Unwrap(env, object); - if (entity == nullptr) { + FsTaskSignal *copySignal = TaskSignalWrapper::Unwrap(env, object); + if (copySignal == nullptr) { + HILOGE("Cannot unwrap copySignal!"); ErrorHandler::Throw(env, EINVAL); return; } - if (entity->taskSignal_ == nullptr) { - HILOGE("Failed to get watcherEntity when stop."); - ErrorHandler::Throw(env, EINVAL); - return; - } - - auto ret = entity->taskSignal_->Cancel(); - if (ret != NO_ERROR) { - HILOGE("Failed to cancel the task."); - ErrorHandler::Throw(env, CANCEL_ERR); + auto ret = copySignal->Cancel(); + if (!ret.IsSuccess()) { + HILOGE("Cannot Cancel!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); return; } } void TaskSignalAni::OnCancel(ani_env *env, [[maybe_unused]] ani_object object) { - auto entity = Unwrap(env, object); - if (entity == nullptr) { + FsTaskSignal *copySignal = TaskSignalWrapper::Unwrap(env, object); + if (copySignal == nullptr) { + HILOGE("Cannot unwrap copySignal!"); ErrorHandler::Throw(env, EINVAL); return; } - if (entity->taskSignal_ == nullptr) { - HILOGE("Failed to get watcherEntity when stop."); - ErrorHandler::Throw(env, EINVAL); - return; - } - - ani_ref globalObj; - auto status = env->GlobalReference_Create(object, &globalObj); - if (status != ANI_OK) { - HILOGE("GlobalReference_Create, err: %{private}d", status); + auto ret = copySignal->OnCancel(); + if (!ret.IsSuccess()) { + HILOGE("Cannot Cancel!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); return; } - ani_vm *vm = nullptr; - env->GetVM(&vm); - auto cb = [vm, &globalObj](string filePath) -> void { - auto env = AniHelper::GetThreadEnv(vm); - if (env == nullptr) { - HILOGE("failed to GetThreadEnv"); - return; - } - - // std::vector vec; - auto [succPath, path] = TypeConverter::ToAniString(env, filePath); - if (!succPath) { - HILOGE("ToAniString failed"); - return; - } - - auto ret = env->Object_CallMethodByName_Void(static_cast(globalObj), - "onCancelCallback", nullptr, path); - if (ret != ANI_OK) { - HILOGE("Call onCancelCallback failed, err: %{private}d", ret); - return; - } - }; - auto callbackContext = std::make_shared(cb); - entity->callbackContextCore_ = callbackContext; - entity->taskSignal_->SetTaskSignalListener(entity); } + } // namespace ANI } // namespace ModuleFileIO } // namespace FileManagement diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h index 6db3301ce..d27e52538 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_ani.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ANI_H -#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ANI_H +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_ANI_H #include @@ -22,13 +22,15 @@ namespace OHOS { namespace FileManagement { namespace ModuleFileIO { namespace ANI { + class TaskSignalAni final { public: static void Cancel(ani_env *env, [[maybe_unused]] ani_object object); static void OnCancel(ani_env *env, [[maybe_unused]] ani_object object); }; + } // namespace ANI } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS -#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ANI_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp new file mode 100644 index 000000000..a80010e95 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp @@ -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. + */ + +#include "task_signal_listener_ani.h" + +#include +#include "ani_helper.h" +#include "ani_signature.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +void TaskSignalListenerAni::OnCancel() +{ + auto filepath = taskSignal->filePath_; + auto task = [this, filepath]() { SendCancelEvent(filepath); }; + AniHelper::SendEventToMainThread(task); +} + +void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const +{ + if (vm == nullptr) { + HILOGE("Cannot send cancel event because the vm is null."); + return; + } + if (signalObj == nullptr) { + HILOGE("Cannot send cancel event because the signalObj is null."); + return; + } + ani_env *env = AniHelper::GetThreadEnv(vm); + if (env == nullptr) { + HILOGE("Cannot send cancel event because the env is null."); + return; + } + auto [succ, aniPath] = TypeConverter::ToAniString(env, filepath); + if (!succ) { + HILOGE("Cannot convert filepath to ani string!"); + return; + } + auto ret = env->Object_CallMethodByName_Void(signalObj, "onCancelCallback", nullptr, aniPath); + if (ret != ANI_OK) { + HILOGE("Call onCancelCallback failed, err: %{private}d", ret); + return; + } +} + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity_core.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h similarity index 47% rename from interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity_core.h rename to interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h index c301442c7..a11be571b 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity_core.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h @@ -13,34 +13,35 @@ * limitations under the License. */ -#ifndef FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_CORE_H -#define FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_CORE_H +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_LISTENER_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_LISTENER_ANI_H -#include "task_signal.h" +#include #include "task_signal_listener.h" +#include "task_signal.h" -namespace OHOS::FileManagement::ModuleFileIO { +namespace OHOS::FileManagement::ModuleFileIO::ANI { using namespace DistributedFS::ModuleTaskSignal; -typedef std::function TaskSignalCb; -class CallbackContextCore { +class TaskSignalListenerAni : public TaskSignalListener { public: - explicit CallbackContextCore(TaskSignalCb cb) : cb(cb) {} - ~CallbackContextCore() = default; - - TaskSignalCb cb; - std::string filePath_; -}; + TaskSignalListenerAni(ani_vm *vm, const ani_object &signalObj, std::shared_ptr taskSignal) + : vm(vm), signalObj(signalObj), taskSignal(taskSignal) {} + void OnCancel() override; -class TaskSignalEntityCore : public TaskSignalListener { public: - TaskSignalEntityCore() = default; - ~TaskSignalEntityCore() override; - void OnCancel() override; + TaskSignalListenerAni() = default; + ~TaskSignalListenerAni() = default; - std::shared_ptr taskSignal_ = nullptr; - std::shared_ptr callbackContextCore_ = nullptr; +private: + void SendCancelEvent(const std::string &filepath) const; + +private: + ani_vm *vm; + ani_object signalObj; + std::shared_ptr taskSignal; }; -} // namespace OHOS::FileManagement::ModuleFileIO -#endif // FILEMANAGEMENT_FILE_API_TASK_SIGNAL_ENTITY_CORE_H \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO::ANI + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_LISTENER_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp new file mode 100644 index 000000000..79be64231 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.cpp @@ -0,0 +1,71 @@ +/* + * 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 "task_signal_wrapper.h" + +#include "ani_signature.h" +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "fs_task_signal.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +FsTaskSignal *TaskSignalWrapper::Unwrap(ani_env *env, ani_object object) +{ + ani_long nativePtr; + auto status = env->Object_GetFieldByName_Long(object, "nativeTaskSignal", &nativePtr); + if (status != ANI_OK) { + HILOGE("Unwrap taskSignal obj failed! status: %{public}d", status); + return nullptr; + } + uintptr_t ptrValue = static_cast(nativePtr); + FsTaskSignal *copySignal = reinterpret_cast(ptrValue); + return copySignal; +} + +bool TaskSignalWrapper::Wrap(ani_env *env, ani_object object, const FsTaskSignal *signal) +{ + if (object == nullptr) { + HILOGE("TaskSignal obj is null!"); + return false; + } + + if (signal == nullptr) { + HILOGE("FsTaskSignal pointer is null!"); + return false; + } + + ani_long ptr = static_cast(reinterpret_cast(signal)); + + auto status = env->Object_SetFieldByName_Long(object, "nativeTaskSignal", ptr); + if (status != ANI_OK) { + HILOGE("Wrap taskSignal obj failed! status: %{public}d", status); + return false; + } + + return true; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h new file mode 100644 index 000000000..2cfd04e4d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.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 INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_WRAPPER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_WRAPPER_H + +#include +#include "fs_task_signal.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class TaskSignalWrapper final { +public: + static FsTaskSignal *Unwrap(ani_env *env, ani_object object); + static bool Wrap(ani_env *env, ani_object object, const FsTaskSignal *signal); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_WRAPPER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp new file mode 100644 index 000000000..d9b4b6ffe --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.cpp @@ -0,0 +1,79 @@ +/* + * 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 "fs_task_signal.h" + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult> FsTaskSignal::Constructor( + shared_ptr taskSignal, shared_ptr signalListener) +{ + if (!taskSignal) { + HILOGE("Invalid taskSignal"); + return FsResult>::Error(EINVAL); + } + if (!signalListener) { + HILOGE("Invalid signalListener"); + return FsResult>::Error(EINVAL); + } + auto copySignal = CreateSharedPtr(); + if (copySignal == nullptr) { + HILOGE("Failed to request heap memory."); + return FsResult>::Error(ENOMEM); + } + copySignal->taskSignal_ = move(taskSignal); + copySignal->signalListener_ = move(signalListener); + return FsResult>::Success(copySignal); +} + +FsResult FsTaskSignal::Cancel() +{ + if (taskSignal_ == nullptr) { + HILOGE("Failed to get taskSignal"); + return FsResult::Error(EINVAL); + } + auto ret = taskSignal_->Cancel(); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to cancel the task."); + return FsResult::Error(CANCEL_ERR); + } + return FsResult::Success(); +} + +FsResult FsTaskSignal::OnCancel() +{ + if (taskSignal_ == nullptr) { + HILOGE("Failed to get taskSignal"); + return FsResult::Error(EINVAL); + } + taskSignal_->SetTaskSignalListener(signalListener_.get()); + return FsResult::Success(); +} + +shared_ptr FsTaskSignal::GetTaskSignal() const +{ + return taskSignal_; +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h new file mode 100644 index 000000000..33161108c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/fs_task_signal.h @@ -0,0 +1,50 @@ +/* + * 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 INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_FS_TASK_SIGNAL_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_FS_TASK_SIGNAL_H + +#include "filemgmt_libfs.h" +#include "task_signal.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace DistributedFS::ModuleTaskSignal; + +class FsTaskSignal { +public: + static FsResult> Constructor( + shared_ptr taskSignal, shared_ptr signalListener); + FsResult Cancel(); + FsResult OnCancel(); + shared_ptr GetTaskSignal() const; + +public: + FsTaskSignal() = default; + ~FsTaskSignal() = default; + FsTaskSignal(const FsTaskSignal &other) = delete; + FsTaskSignal &operator=(const FsTaskSignal &other) = delete; + +private: + shared_ptr taskSignal_ = nullptr; + shared_ptr signalListener_ = nullptr; +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_FS_TASK_SIGNAL_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp index e086c5ee1..7e84bce8f 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp @@ -21,6 +21,10 @@ #include "error_handler.h" #include "file_utils.h" #include "filemgmt_libhilog.h" +#include "fs_task_signal.h" +#include "progress_listener_ani.h" +#include "task_signal_listener_ani.h" +#include "task_signal_wrapper.h" #include "type_converter.h" namespace OHOS { @@ -31,112 +35,100 @@ using namespace std; using namespace OHOS::FileManagement::ModuleFileIO; using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; -static void SetProgressListenerCb(ani_env *env, ani_ref &callback, CopyOptions &opts) +static bool ParseListenerFromOptionArg(ani_env *env, const ani_object &options, CopyOptions &opts) { + ani_ref prog; + if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "progressListener", &prog)) { + HILOGE("Illegal options.progressListener type"); + return false; + } + + ani_boolean isUndefined = true; + env->Reference_IsUndefined(prog, &isUndefined); + if (isUndefined) { + return true; + } + + ani_ref cbRef; + if (ANI_OK != env->GlobalReference_Create(prog, &cbRef)) { + HILOGE("Illegal options.progressListener type"); + return false; + } + ani_vm *vm = nullptr; env->GetVM(&vm); + auto listener = CreateSharedPtr(vm, cbRef); + if (listener == nullptr) { + HILOGE("Failed to request heap memory."); + return false; + } - opts.listenerCb = [vm, &callback](uint64_t progressSize, uint64_t totalSize) -> void { - ani_status ret; - ani_object progress = {}; - auto classDesc = FS::ProgressInner::classDesc.c_str(); - ani_class cls; - - auto env = AniHelper::GetThreadEnv(vm); - if (env == nullptr) { - HILOGE("failed to GetThreadEnv"); - return; - } - - if (progressSize > MAX_VALUE || totalSize > MAX_VALUE) { - HILOGE("progressSize or totalSize exceed MAX_VALUE: %{private}" PRIu64 " %{private}" PRIu64, progressSize, - totalSize); - } - - if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { - HILOGE("Not found %{private}s, err: %{private}d", classDesc, ret); - return; - } - - auto ctorDesc = FS::ProgressInner::ctorDesc.c_str(); - auto ctorSig = FS::ProgressInner::ctorSig.c_str(); - ani_method ctor; - if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { - HILOGE("Not found ctor, err: %{private}d", ret); - return; - } - - if ((ret = env->Object_New(cls, ctor, &progress, ani_double(static_cast(progressSize)), - ani_double(static_cast(totalSize)))) != ANI_OK) { - HILOGE("New ProgressInner Fail, err: %{private}d", ret); - return; - } - - std::vector vec; - vec.push_back(progress); - ani_ref result; - ret = env->FunctionalObject_Call(static_cast(callback), vec.size(), vec.data(), &result); - if (ret != ANI_OK) { - HILOGE("FunctionalObject_Call, err: %{private}d", ret); - return; - } - }; + opts.progressListener = move(listener); + return true; } -static bool SetTaskSignal(ani_env *env, ani_ref ©Signal, CopyOptions &opts) +static bool ParseCopySignalFromOptionArg(ani_env *env, const ani_object &options, CopyOptions &opts) { - ani_status ret; - auto taskSignalEntityCore = CreateSharedPtr(); - if (taskSignalEntityCore == nullptr) { + ani_ref prog; + if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "copySignal", &prog)) { + HILOGE("Illegal options.CopySignal type"); + return false; + } + + ani_boolean isUndefined = true; + env->Reference_IsUndefined(prog, &isUndefined); + if (isUndefined) { + return true; + } + + auto taskSignal = CreateSharedPtr(); + if (taskSignal == nullptr) { HILOGE("Failed to request heap memory."); return false; } - ret = env->Object_SetFieldByName_Long(static_cast(copySignal), "nativeTaskSignal", - reinterpret_cast(taskSignalEntityCore.get())); - if (ret != ANI_OK) { - HILOGE("Object set nativeTaskSignal err: %{private}d", ret); + auto signalObj = static_cast(prog); + ani_vm *vm = nullptr; + env->GetVM(&vm); + auto listener = CreateSharedPtr(vm, signalObj, taskSignal); + if (listener == nullptr) { + HILOGE("Failed to request heap memory."); return false; } - taskSignalEntityCore->taskSignal_ = std::make_shared(); - opts.taskSignalEntityCore = move(taskSignalEntityCore); + auto result = FsTaskSignal::Constructor(taskSignal, listener); + if (!result.IsSuccess()) { + return false; + } + auto copySignal = result.GetData().value(); + auto succ = TaskSignalWrapper::Wrap(env, signalObj, copySignal.get()); + if (!succ) { + return false; + } + + opts.copySignal = move(copySignal); return true; } -static tuple> ParseOptions(ani_env *env, ani_ref &cb, ani_object &options) +static tuple> ParseOptions(ani_env *env, ani_object &options) { ani_boolean isUndefined; - ani_status ret; env->Reference_IsUndefined(options, &isUndefined); if (isUndefined) { return { true, nullopt }; } CopyOptions opts; - ani_ref prog; - if ((ret = env->Object_GetPropertyByName_Ref(options, "progressListener", &prog)) != ANI_OK) { - HILOGE("Object_GetPropertyByName_Ref progressListener, err: %{private}d", ret); + auto succ = ParseListenerFromOptionArg(env, options, opts); + if (!succ) { return { false, nullopt }; } - env->Reference_IsUndefined(prog, &isUndefined); - if (!isUndefined) { - env->GlobalReference_Create(prog, &cb); - SetProgressListenerCb(env, cb, opts); - } - ani_ref signal; - if ((ret = env->Object_GetPropertyByName_Ref(options, "copySignal", &signal)) != ANI_OK) { - HILOGE("Object_GetPropertyByName_Ref copySignal, err: %{private}d", ret); + succ = ParseCopySignalFromOptionArg(env, options, opts); + if (!succ) { return { false, nullopt }; } - env->Reference_IsUndefined(signal, &isUndefined); - if (!isUndefined) { - if (!SetTaskSignal(env, signal, opts)) { - return { false, nullopt }; - } - } return { true, make_optional(move(opts)) }; } @@ -146,24 +138,15 @@ void CopyAni::CopySync( { auto [succSrc, src] = TypeConverter::ToUTF8String(env, srcUri); auto [succDest, dest] = TypeConverter::ToUTF8String(env, destUri); - if (!succSrc || !succDest) { - HILOGE("The first/second argument requires filepath"); - ErrorHandler::Throw(env, EINVAL); - return; - } + auto [succOpts, opts] = ParseOptions(env, options); - ani_ref cb; - auto [succOpts, opts] = ParseOptions(env, cb, options); - if (!succOpts) { - HILOGE("Failed to parse opts"); - ErrorHandler::Throw(env, EINVAL); + if (!succSrc || !succDest || !succOpts) { + HILOGE("The first/second/third argument requires uri/uri/napi_function"); + ErrorHandler::Throw(env, E_PARAMS); return; } auto ret = CopyCore::DoCopy(src, dest, opts); - if (opts.has_value() && opts->listenerCb != nullptr) { - env->GlobalReference_Delete(cb); - } if (!ret.IsSuccess()) { HILOGE("DoCopy failed!"); const FsError &err = ret.GetError(); diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp index f3d4613d7..45403ca6d 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -60,25 +60,9 @@ constexpr int BUF_SIZE = 1024; constexpr size_t MAX_SIZE = 1024 * 1024 * 4; constexpr std::chrono::milliseconds NOTIFY_PROGRESS_DELAY(300); std::recursive_mutex CopyCore::mutex_; -std::map> CopyCore::jsCbMap_; +std::map> CopyCore::callbackMap_; -static string GetModeFromFlags(unsigned int flags) -{ - const string readMode = "r"; - const string writeMode = "w"; - const string appendMode = "a"; - const string truncMode = "t"; - string mode = readMode; - mode += (((flags & O_RDWR) == O_RDWR) ? writeMode : ""); - mode = (((flags & O_WRONLY) == O_WRONLY) ? writeMode : mode); - if (mode != readMode) { - mode += ((flags & O_TRUNC) ? truncMode : ""); - mode += ((flags & O_APPEND) ? appendMode : ""); - } - return mode; -} - -static int OpenSrcFile(const string &srcPth, std::shared_ptr infos, int32_t &srcFd) +static int OpenSrcFile(const string &srcPth, std::shared_ptr infos, int32_t &srcFd) { Uri uri(infos->srcUri); if (uri.GetAuthority() == MEDIA) { @@ -93,7 +77,7 @@ static int OpenSrcFile(const string &srcPth, std::shared_ptr info HILOGE("Failed to connect to datashare"); return E_PERMISSION; } - srcFd = dataShareHelper->OpenFile(uri, GetModeFromFlags(O_RDONLY)); + srcFd = dataShareHelper->OpenFile(uri, FsUtils::GetModeFromFlags(O_RDONLY)); if (srcFd < 0) { HILOGE("Open media uri by data share fail. ret = %{public}d", srcFd); return EPERM; @@ -108,18 +92,17 @@ static int OpenSrcFile(const string &srcPth, std::shared_ptr info return ERRNO_NOERR; } -static int SendFileCore(std::unique_ptr srcFdg, - std::unique_ptr destFdg, - std::shared_ptr infos) +static int SendFileCore(std::unique_ptr srcFdg, std::unique_ptr destFdg, + std::shared_ptr infos) { - std::unique_ptr sendFileReq = { - new (nothrow) uv_fs_t, FsUtils::FsReqCleanup }; + std::unique_ptr sendFileReq = { new (nothrow) uv_fs_t, + FsUtils::FsReqCleanup }; if (sendFileReq == nullptr) { HILOGE("Failed to request heap memory."); return ENOMEM; } int64_t offset = 0; - struct stat srcStat{}; + struct stat srcStat {}; if (fstat(srcFdg->GetFD(), &srcStat) < 0) { HILOGE("Failed to get stat of file by fd: %{public}d ,errno = %{public}d", srcFdg->GetFD(), errno); return errno; @@ -127,15 +110,13 @@ static int SendFileCore(std::unique_ptr srcFdg, int32_t ret = 0; int64_t size = static_cast(srcStat.st_size); while (size >= 0) { - ret = uv_fs_sendfile(nullptr, sendFileReq.get(), destFdg->GetFD(), srcFdg->GetFD(), - offset, MAX_SIZE, nullptr); + ret = uv_fs_sendfile(nullptr, sendFileReq.get(), destFdg->GetFD(), srcFdg->GetFD(), offset, MAX_SIZE, nullptr); if (ret < 0) { HILOGE("Failed to sendfile by errno : %{public}d", errno); return errno; } if (infos != nullptr && infos->taskSignal != nullptr) { if (infos->taskSignal->CheckCancelIfNeed(infos->srcPath)) { - HILOGE("===Copy Task Canceled Success"); return ECANCELED; } } @@ -159,10 +140,7 @@ bool CopyCore::IsValidUri(const std::string &uri) bool CopyCore::ValidOperand(std::string uriStr) { - if (IsValidUri(uriStr)) { - return true; - } - return false; + return IsValidUri(uriStr); } bool CopyCore::IsRemoteUri(const std::string &uri) @@ -228,7 +206,7 @@ int CopyCore::CheckOrCreatePath(const std::string &destPath) return ERRNO_NOERR; } -int CopyCore::CopyFile(const string &src, const string &dest, std::shared_ptr infos) +int CopyCore::CopyFile(const string &src, const string &dest, std::shared_ptr infos) { HILOGD("src = %{public}s, dest = %{public}s", GetAnonyString(src).c_str(), GetAnonyString(dest).c_str()); int32_t srcFd = -1; @@ -264,7 +242,7 @@ int CopyCore::MakeDir(const string &path) return ERRNO_NOERR; } -int CopyCore::CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos) +int CopyCore::CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos) { std::error_code errCode; if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { @@ -286,14 +264,14 @@ int CopyCore::CopySubDir(const string &srcPath, const string &destPath, std::sha } { std::lock_guard lock(CopyCore::mutex_); - auto iter = CopyCore::jsCbMap_.find(*infos); + auto iter = CopyCore::callbackMap_.find(*infos); auto receiveInfo = CreateSharedPtr(); if (receiveInfo == nullptr) { HILOGE("Failed to request heap memory."); return ENOMEM; } receiveInfo->path = destPath; - if (iter == CopyCore::jsCbMap_.end() || iter->second == nullptr) { + if (iter == CopyCore::callbackMap_.end() || iter->second == nullptr) { HILOGE("Failed to find infos, srcPath = %{public}s, destPath = %{public}s", GetAnonyString(infos->srcPath).c_str(), GetAnonyString(infos->destPath).c_str()); return UNKNOWN_ERR; @@ -329,11 +307,11 @@ static void Deleter(struct NameList *arg) arg = nullptr; } -std::string CopyCore::GetRealPath(const std::string& path) +std::string CopyCore::GetRealPath(const std::string &path) { fs::path tempPath(path); - fs::path realPath{}; - for (const auto& component : tempPath) { + fs::path realPath {}; + for (const auto &component : tempPath) { if (component == ".") { continue; } else if (component == "..") { @@ -345,7 +323,7 @@ std::string CopyCore::GetRealPath(const std::string& path) return realPath.string(); } -uint64_t CopyCore::GetDirSize(std::shared_ptr infos, std::string path) +uint64_t CopyCore::GetDirSize(std::shared_ptr infos, std::string path) { unique_ptr pNameList = { new (nothrow) struct NameList, Deleter }; if (pNameList == nullptr) { @@ -374,7 +352,7 @@ uint64_t CopyCore::GetDirSize(std::shared_ptr infos, std::string return size; } -int CopyCore::RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr infos) +int CopyCore::RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr infos) { unique_ptr pNameList = { new (nothrow) struct NameList, Deleter }; if (pNameList == nullptr) { @@ -404,7 +382,7 @@ int CopyCore::RecurCopyDir(const string &srcPath, const string &destPath, std::s return ERRNO_NOERR; } -int CopyCore::CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos) +int CopyCore::CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos) { HILOGD("CopyDirFunc in, src = %{public}s, dest = %{public}s", GetAnonyString(src).c_str(), GetAnonyString(dest).c_str()); @@ -421,7 +399,7 @@ int CopyCore::CopyDirFunc(const string &src, const string &dest, std::shared_ptr return CopySubDir(src, destStr, infos); } -int CopyCore::ExecLocal(std::shared_ptr infos, std::shared_ptr callback) +int CopyCore::ExecLocal(std::shared_ptr infos, std::shared_ptr callback) { if (infos->isFile) { if (infos->srcPath == infos->destPath) { @@ -446,8 +424,7 @@ int CopyCore::ExecLocal(std::shared_ptr infos, std::shared_ptr infos, - std::shared_ptr callback) +int CopyCore::SubscribeLocalListener(std::shared_ptr infos, std::shared_ptr callback) { infos->notifyFd = inotify_init(); if (infos->notifyFd < 0) { @@ -465,7 +442,7 @@ int CopyCore::SubscribeLocalListener(std::shared_ptr infos, if (newWd < 0) { auto errCode = errno; HILOGE("Failed to add watch, errno = %{public}d, notifyFd: %{public}d, destPath: %{public}s", errno, - infos->notifyFd, infos->destPath.c_str()); + infos->notifyFd, infos->destPath.c_str()); CloseNotifyFdLocked(infos, callback); return errCode; } @@ -489,66 +466,73 @@ int CopyCore::SubscribeLocalListener(std::shared_ptr infos, return err; } -std::shared_ptr CopyCore::RegisterListener(const std::shared_ptr &infos) +std::shared_ptr CopyCore::RegisterListener(const std::shared_ptr &infos) { - auto callback = CreateSharedPtr(infos->listenerCb); + auto callback = CreateSharedPtr(infos->listener); if (callback == nullptr) { HILOGE("Failed to request heap memory."); return nullptr; } std::lock_guard lock(mutex_); - auto iter = jsCbMap_.find(*infos); - if (iter != jsCbMap_.end()) { + auto iter = callbackMap_.find(*infos); + if (iter != callbackMap_.end()) { HILOGE("CopyCore::RegisterListener, already registered."); return nullptr; } - jsCbMap_.insert({ *infos, callback }); + callbackMap_.insert({ *infos, callback }); return callback; } -void CopyCore::UnregisterListener(std::shared_ptr fileInfos) +void CopyCore::UnregisterListener(std::shared_ptr fileInfos) { if (fileInfos == nullptr) { HILOGE("fileInfos is nullptr"); return; } std::lock_guard lock(mutex_); - auto iter = jsCbMap_.find(*fileInfos); - if (iter == jsCbMap_.end()) { + auto iter = callbackMap_.find(*fileInfos); + if (iter == callbackMap_.end()) { HILOGI("It is not be registered."); return; } - jsCbMap_.erase(*fileInfos); + callbackMap_.erase(*fileInfos); } -void CopyCore::ReceiveComplete(std::shared_ptr entry) +void CopyCore::ReceiveComplete(std::shared_ptr entry) { if (entry == nullptr) { HILOGE("entry pointer is nullptr."); return; } + if (entry->callback == nullptr) { + HILOGE("entry callback pointer is nullptr."); + return; + } auto processedSize = entry->progressSize; if (processedSize < entry->callback->maxProgressSize) { - HILOGE("enter ReceiveComplete2"); return; } entry->callback->maxProgressSize = processedSize; - - entry->callback->listenerCb(processedSize, entry->totalSize); + auto listener = entry->callback->listener; + if (listener == nullptr) { + HILOGE("listener pointer is nullptr."); + return; + } + listener->InvokeListener(processedSize, entry->totalSize); } -UvEntryCore *CopyCore::GetUVEntry(std::shared_ptr infos) +FsUvEntry *CopyCore::GetUVEntry(std::shared_ptr infos) { - UvEntryCore *entry = nullptr; + FsUvEntry *entry = nullptr; { std::lock_guard lock(mutex_); - auto iter = jsCbMap_.find(*infos); - if (iter == jsCbMap_.end()) { + auto iter = callbackMap_.find(*infos); + if (iter == callbackMap_.end()) { HILOGE("Failed to find callback"); return nullptr; } auto callback = iter->second; - entry = new (std::nothrow) UvEntryCore(iter->second, infos); + entry = new (std::nothrow) FsUvEntry(iter->second, infos); if (entry == nullptr) { HILOGE("entry ptr is nullptr."); return nullptr; @@ -559,9 +543,9 @@ UvEntryCore *CopyCore::GetUVEntry(std::shared_ptr infos) return entry; } -void CopyCore::OnFileReceive(std::shared_ptr infos) +void CopyCore::OnFileReceive(std::shared_ptr infos) { - std::shared_ptr entry(GetUVEntry(infos)); + std::shared_ptr entry(GetUVEntry(infos)); if (entry == nullptr) { HILOGE("failed to get uv entry"); return; @@ -569,25 +553,22 @@ void CopyCore::OnFileReceive(std::shared_ptr infos) ReceiveComplete(entry); } -std::shared_ptr CopyCore::GetReceivedInfo(int wd, std::shared_ptr callback) +std::shared_ptr CopyCore::GetReceivedInfo(int wd, std::shared_ptr callback) { - auto it = find_if(callback->wds.begin(), callback->wds.end(), [wd](const auto& item) { - return item.first == wd; - }); + auto it = find_if(callback->wds.begin(), callback->wds.end(), [wd](const auto &item) { return item.first == wd; }); if (it != callback->wds.end()) { return it->second; } return nullptr; } -bool CopyCore::CheckFileValid(const std::string &filePath, std::shared_ptr infos) +bool CopyCore::CheckFileValid(const std::string &filePath, std::shared_ptr infos) { return infos->filePaths.count(filePath) != 0; } -int CopyCore::UpdateProgressSize(const std::string &filePath, - std::shared_ptr receivedInfo, - std::shared_ptr callback) +int CopyCore::UpdateProgressSize( + const std::string &filePath, std::shared_ptr receivedInfo, std::shared_ptr callback) { auto [err, fileSize] = GetFileSize(filePath); if (err != ERRNO_NOERR) { @@ -608,18 +589,18 @@ int CopyCore::UpdateProgressSize(const std::string &filePath, return ERRNO_NOERR; } -std::shared_ptr CopyCore::GetRegisteredListener(std::shared_ptr infos) +std::shared_ptr CopyCore::GetRegisteredListener(std::shared_ptr infos) { std::lock_guard lock(mutex_); - auto iter = jsCbMap_.find(*infos); - if (iter == jsCbMap_.end()) { + auto iter = callbackMap_.find(*infos); + if (iter == callbackMap_.end()) { HILOGE("It is not registered."); return nullptr; } return iter->second; } -void CopyCore::CloseNotifyFd(std::shared_ptr infos, std::shared_ptr callback) +void CopyCore::CloseNotifyFd(std::shared_ptr infos, std::shared_ptr callback) { callback->closed = false; infos->eventFd = -1; @@ -631,7 +612,7 @@ void CopyCore::CloseNotifyFd(std::shared_ptr infos, std::shared_p } } -void CopyCore::CloseNotifyFdLocked(std::shared_ptr infos, std::shared_ptr callback) +void CopyCore::CloseNotifyFdLocked(std::shared_ptr infos, std::shared_ptr callback) { { lock_guard lock(callback->readMutex); @@ -645,7 +626,7 @@ void CopyCore::CloseNotifyFdLocked(std::shared_ptr infos, std::sh } tuple CopyCore::HandleProgress( - inotify_event *event, std::shared_ptr infos, std::shared_ptr callback) + inotify_event *event, std::shared_ptr infos, std::shared_ptr callback) { if (callback == nullptr) { return { true, EINVAL, false }; @@ -674,14 +655,15 @@ tuple CopyCore::HandleProgress( return { true, callback->errorCode, true }; } -void CopyCore::ReadNotifyEvent(std::shared_ptr infos) +void CopyCore::ReadNotifyEvent(std::shared_ptr infos) { char buf[BUF_SIZE] = { 0 }; struct inotify_event *event = nullptr; int len = 0; int64_t index = 0; auto callback = GetRegisteredListener(infos); - while (infos->run && ((len = read(infos->notifyFd, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {} + while (infos->run && ((len = read(infos->notifyFd, &buf, sizeof(buf))) < 0) && (errno == EINTR)) { + } while (infos->run && index < len) { event = reinterpret_cast(buf + index); auto [needContinue, errCode, needSend] = HandleProgress(event, infos, callback); @@ -706,7 +688,7 @@ void CopyCore::ReadNotifyEvent(std::shared_ptr infos) } } -void CopyCore::ReadNotifyEventLocked(std::shared_ptr infos, std::shared_ptr callback) +void CopyCore::ReadNotifyEventLocked(std::shared_ptr infos, std::shared_ptr callback) { { std::lock_guard lock(callback->readMutex); @@ -728,7 +710,7 @@ void CopyCore::ReadNotifyEventLocked(std::shared_ptr infos, std:: } } -void CopyCore::GetNotifyEvent(std::shared_ptr infos) +void CopyCore::GetNotifyEvent(std::shared_ptr infos) { auto callback = GetRegisteredListener(infos); if (callback == nullptr) { @@ -760,17 +742,16 @@ void CopyCore::GetNotifyEvent(std::shared_ptr infos) } { std::unique_lock lock(callback->cvLock); - callback->cv.wait_for(lock, std::chrono::microseconds(SLEEP_TIME), [callback]() -> bool { - return callback->notifyFd == -1; - }); + callback->cv.wait_for( + lock, std::chrono::microseconds(SLEEP_TIME), [callback]() -> bool { return callback->notifyFd == -1; }); } } } -tuple> CopyCore::CreateFileInfos( - const std::string &srcUri, const std::string &destUri, std::optional options) +tuple> CopyCore::CreateFileInfos( + const std::string &srcUri, const std::string &destUri, const std::optional &options) { - auto infos = CreateSharedPtr(); + auto infos = CreateSharedPtr(); if (infos == nullptr) { HILOGE("Failed to request heap memory."); return { ENOMEM, nullptr }; @@ -785,29 +766,29 @@ tuple> CopyCore::CreateFileInfos( infos->destPath = GetRealPath(infos->destPath); infos->isFile = IsMediaUri(infos->srcUri) || IsFile(infos->srcPath); infos->notifyTime = std::chrono::steady_clock::now() + NOTIFY_PROGRESS_DELAY; - if (options != std::nullopt) { - if (options.value().listenerCb) { + if (options.has_value()) { + auto listener = options.value().progressListener; + if (listener) { infos->hasListener = true; - infos->listenerCb = options.value().listenerCb; + infos->listener = listener; } - if (options.value().taskSignalEntityCore != nullptr) { - infos->taskSignal = options.value().taskSignalEntityCore->taskSignal_; + auto copySignal = options.value().copySignal; + if (copySignal) { + infos->taskSignal = copySignal->GetTaskSignal(); } } return { ERRNO_NOERR, infos }; } -void CopyCore::StartNotify(std::shared_ptr infos, std::shared_ptr callback) +void CopyCore::StartNotify(std::shared_ptr infos, std::shared_ptr callback) { if (infos->hasListener && callback != nullptr) { - callback->notifyHandler = std::thread([infos] { - GetNotifyEvent(infos); - }); + callback->notifyHandler = std::thread([infos] { GetNotifyEvent(infos); }); } } -int CopyCore::ExecCopy(std::shared_ptr infos) +int CopyCore::ExecCopy(std::shared_ptr infos) { if (infos->isFile && IsFile(infos->destPath)) { // copyFile @@ -826,25 +807,18 @@ int CopyCore::ExecCopy(std::shared_ptr infos) return EINVAL; } -int CopyCore::ValidParam(const string& src, const string& dest, - std::optional options, - std::shared_ptr &fileInfos) +bool CopyCore::ValidParams(const string &src, const string &dest) { auto succSrc = ValidOperand(src); auto succDest = ValidOperand(dest); if (!succSrc || !succDest) { HILOGE("The first/second argument requires uri/uri"); - return E_PARAMS; - } - auto [errCode, infos] = CreateFileInfos(src, dest, options); - if (errCode != ERRNO_NOERR) { - return errCode; + return false; } - fileInfos = infos; - return ERRNO_NOERR; + return true; } -void CopyCore::WaitNotifyFinished(std::shared_ptr callback) +void CopyCore::WaitNotifyFinished(std::shared_ptr callback) { if (callback != nullptr) { if (callback->notifyHandler.joinable()) { @@ -853,7 +827,7 @@ void CopyCore::WaitNotifyFinished(std::shared_ptr callback) } } -void CopyCore::CopyComplete(std::shared_ptr infos, std::shared_ptr callback) +void CopyCore::CopyComplete(std::shared_ptr infos, std::shared_ptr callback) { if (callback != nullptr && infos->hasListener) { callback->progressSize = callback->totalSize; @@ -861,12 +835,16 @@ void CopyCore::CopyComplete(std::shared_ptr infos, std::shared_pt } } -FsResult CopyCore::DoCopy(const string& src, const string& dest, std::optional &options) +FsResult CopyCore::DoCopy(const string &src, const string &dest, std::optional &options) { - std::shared_ptr infos = nullptr; - auto result = ValidParam(src, dest, options, infos); - if (result != ERRNO_NOERR) { - return FsResult::Error(result); + auto isValid = ValidParams(src, dest); + if (!isValid) { + return FsResult::Error(E_PARAMS); + } + + auto [errCode, infos] = CreateFileInfos(src, dest, options); + if (errCode != ERRNO_NOERR) { + return FsResult::Error(errCode); } auto callback = RegisterListener(infos); @@ -878,23 +856,25 @@ FsResult CopyCore::DoCopy(const string& src, const string& dest, std::opti if (infos->taskSignal != nullptr) { infos->taskSignal->MarkRemoteTask(); } - auto ret = TransListenerCore::CopyFileFromSoftBus(infos->srcUri, infos->destUri, - infos, std::move(callback)); + auto ret = TransListenerCore::CopyFileFromSoftBus(infos->srcUri, infos->destUri, infos, std::move(callback)); + UnregisterListener(infos); if (ret != ERRNO_NOERR) { return FsResult::Error(ret); } else { return FsResult::Success(); } } - result = CopyCore::ExecLocal(infos, callback); + auto result = CopyCore::ExecLocal(infos, callback); CloseNotifyFdLocked(infos, callback); infos->run = false; WaitNotifyFinished(callback); if (result != ERRNO_NOERR) { infos->exceptionCode = result; + UnregisterListener(infos); return FsResult::Error(infos->exceptionCode); } CopyComplete(infos, callback); + UnregisterListener(infos); if (infos->exceptionCode != ERRNO_NOERR) { return FsResult::Error(infos->exceptionCode); } else { diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_core.h index 58aa4f999..387792260 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -13,20 +13,20 @@ * limitations under the License. */ -#ifndef FILEMANAGEMENT_FILE_API_COPY_CORE_H -#define FILEMANAGEMENT_FILE_API_COPY_CORE_H +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H #include #include #include -#include #include +#include #include "bundle_mgr_client_impl.h" #include "filemgmt_libfs.h" #include "filemgmt_libhilog.h" -#include "task_signal.h" -#include "task_signal_entity_core.h" +#include "fs_task_signal.h" +#include "i_progress_listener.h" namespace OHOS { namespace FileManagement { @@ -34,12 +34,10 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::AppExecFwk; using namespace DistributedFS::ModuleTaskSignal; -const uint64_t MAX_VALUE = 0x7FFFFFFFFFFFFFFF; -typedef std::function ProgressListenerCb; struct CopyOptions { - ProgressListenerCb listenerCb; - std::shared_ptr taskSignalEntityCore; + std::shared_ptr progressListener; + std::shared_ptr copySignal; }; struct ReceiveInfo { @@ -47,8 +45,8 @@ struct ReceiveInfo { std::map fileList; // filename, proceededSize }; -struct CallbackObjectCore { - ProgressListenerCb listenerCb; +struct FsCallbackObject { + std::shared_ptr listener = nullptr; int32_t notifyFd = -1; int32_t eventFd = -1; std::vector>> wds; @@ -62,7 +60,7 @@ struct CallbackObjectCore { std::mutex cvLock; bool reading = false; bool closed = false; - explicit CallbackObjectCore(ProgressListenerCb cb) : listenerCb(cb) {} + explicit FsCallbackObject(std::shared_ptr listener) : listener(listener) {} void CloseFd() { @@ -80,13 +78,13 @@ struct CallbackObjectCore { notifyFd = -1; } - ~CallbackObjectCore() + ~FsCallbackObject() { CloseFd(); } }; -struct FileInfosCore { +struct FsFileInfos { std::string srcUri; std::string destUri; std::string srcPath; @@ -97,15 +95,15 @@ struct FileInfosCore { int32_t eventFd = -1; bool run = true; bool hasListener = false; - ProgressListenerCb listenerCb; + std::shared_ptr listener = nullptr; std::shared_ptr taskSignal = nullptr; std::set filePaths; - int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. - bool operator==(const FileInfosCore &infos) const + int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions. + bool operator==(const FsFileInfos &infos) const { return (srcUri == infos.srcUri && destUri == infos.destUri); } - bool operator<(const FileInfosCore &infos) const + bool operator<(const FsFileInfos &infos) const { if (srcUri == infos.srcUri) { return destUri < infos.destUri; @@ -114,73 +112,65 @@ struct FileInfosCore { } }; -struct UvEntryCore { - std::shared_ptr callback; - std::shared_ptr fileInfos; +struct FsUvEntry { + std::shared_ptr callback; + std::shared_ptr fileInfos; uint64_t progressSize = 0; uint64_t totalSize = 0; - UvEntryCore(const std::shared_ptr &cb, std::shared_ptr fileInfos) + FsUvEntry(const std::shared_ptr &cb, std::shared_ptr fileInfos) : callback(cb), fileInfos(fileInfos) { } - explicit UvEntryCore(const std::shared_ptr &cb) : callback(cb) {} + explicit FsUvEntry(const std::shared_ptr &cb) : callback(cb) {} }; class CopyCore final { public: - static std::map> jsCbMap_; - static void UnregisterListener(std::shared_ptr fileInfos); - static std::recursive_mutex mutex_; - static FsResult DoCopy(const string& src, const string& dest, std::optional &options); + static FsResult DoCopy(const string &src, const string &dest, std::optional &options); private: - // operator of napi + // operator of params static bool ValidOperand(std::string uriStr); static int CheckOrCreatePath(const std::string &destPath); - static int ValidParam(const string& src, const string& dest, std::optional options, - std::shared_ptr &fileInfos); + static bool ValidParams(const string &src, const string &dest); // operator of local listener - static int ExecLocal(std::shared_ptr infos, std::shared_ptr callback); - static void CopyComplete(std::shared_ptr infos, std::shared_ptr callback); - static void WaitNotifyFinished(std::shared_ptr callback); - static void ReadNotifyEvent(std::shared_ptr infos); - static void ReadNotifyEventLocked(std::shared_ptr infos, - std::shared_ptr callback); - static int SubscribeLocalListener(std::shared_ptr infos, - std::shared_ptr callback); - static std::shared_ptr RegisterListener( - const std::shared_ptr &infos); - static void OnFileReceive(std::shared_ptr infos); - static void GetNotifyEvent(std::shared_ptr infos); - static void StartNotify(std::shared_ptr infos, std::shared_ptr callback); - static UvEntryCore *GetUVEntry(std::shared_ptr infos); - static void ReceiveComplete(std::shared_ptr entry); - static std::shared_ptr GetRegisteredListener(std::shared_ptr infos); - static void CloseNotifyFd(std::shared_ptr infos, std::shared_ptr callback); - static void CloseNotifyFdLocked(std::shared_ptr infos, - std::shared_ptr callback); + static std::shared_ptr RegisterListener(const std::shared_ptr &infos); + static std::shared_ptr GetRegisteredListener(std::shared_ptr infos); + static void UnregisterListener(std::shared_ptr fileInfos); + static int ExecLocal(std::shared_ptr infos, std::shared_ptr callback); + static void CopyComplete(std::shared_ptr infos, std::shared_ptr callback); + static void WaitNotifyFinished(std::shared_ptr callback); + static void ReadNotifyEvent(std::shared_ptr infos); + static void ReadNotifyEventLocked(std::shared_ptr infos, std::shared_ptr callback); + static int SubscribeLocalListener(std::shared_ptr infos, std::shared_ptr callback); + static void OnFileReceive(std::shared_ptr infos); + static void GetNotifyEvent(std::shared_ptr infos); + static void StartNotify(std::shared_ptr infos, std::shared_ptr callback); + static FsUvEntry *GetUVEntry(std::shared_ptr infos); + static void ReceiveComplete(std::shared_ptr entry); + static void CloseNotifyFd(std::shared_ptr infos, std::shared_ptr callback); + static void CloseNotifyFdLocked(std::shared_ptr infos, std::shared_ptr callback); // operator of file - static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr infos); + static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr infos); static tuple GetFileSize(const std::string &path); - static uint64_t GetDirSize(std::shared_ptr infos, std::string path); - static int CopyFile(const string &src, const string &dest, std::shared_ptr infos); + static uint64_t GetDirSize(std::shared_ptr infos, std::string path); + static int CopyFile(const string &src, const string &dest, std::shared_ptr infos); static int MakeDir(const string &path); - static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); - static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos); - static tuple> CreateFileInfos( - const std::string &srcUri, const std::string &destUri, std::optional options); - static int ExecCopy(std::shared_ptr infos); + static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr infos); + static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr infos); + static tuple> CreateFileInfos( + const std::string &srcUri, const std::string &destUri, const std::optional &options); + static int ExecCopy(std::shared_ptr infos); // operator of file size - static int UpdateProgressSize(const std::string &filePath, - std::shared_ptr receivedInfo, - std::shared_ptr callback); + static int UpdateProgressSize(const std::string &filePath, std::shared_ptr receivedInfo, + std::shared_ptr callback); static tuple HandleProgress( - inotify_event *event, std::shared_ptr infos, std::shared_ptr callback); - static std::shared_ptr GetReceivedInfo(int wd, std::shared_ptr callback); - static bool CheckFileValid(const std::string &filePath, std::shared_ptr infos); + inotify_event *event, std::shared_ptr infos, std::shared_ptr callback); + static std::shared_ptr GetReceivedInfo(int wd, std::shared_ptr callback); + static bool CheckFileValid(const std::string &filePath, std::shared_ptr infos); // operator of uri or path static bool IsValidUri(const std::string &uri); @@ -189,10 +179,14 @@ private: static bool IsFile(const std::string &path); static bool IsMediaUri(const std::string &uriPath); static std::string ConvertUriToPath(const std::string &uri); - static std::string GetRealPath(const std::string& path); + static std::string GetRealPath(const std::string &path); + +private: + static std::recursive_mutex mutex_; + static std::map> callbackMap_; }; } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS -#endif // FILEMANAGEMENT_FILE_API_COPY_CORE_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp new file mode 100644 index 000000000..58be19337 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp @@ -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. + */ + +#include "progress_listener_ani.h" + +#include +#include "ani_helper.h" +#include "ani_signature.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +void ProgressListenerAni::InvokeListener(uint64_t progressSize, uint64_t totalSize) const +{ + auto task = [this, progressSize, totalSize]() { SendCopyProgress(progressSize, totalSize); }; + AniHelper::SendEventToMainThread(task); +} + +static ani_object WrapCopyProgress(ani_env *env, uint64_t progressSize, uint64_t totalSize) +{ + auto classDesc = FS::ProgressInner::classDesc.c_str(); + ani_class cls; + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{private}s", classDesc); + return nullptr; + } + auto ctorDesc = FS::ProgressInner::ctorDesc.c_str(); + auto ctorSig = FS::ProgressInner::ctorSig.c_str(); + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{private}s", classDesc); + return nullptr; + } + + const ani_double aniProgressSize = static_cast(progressSize <= MAX_VALUE ? progressSize : 0); + const ani_double aniTotalSize = static_cast(totalSize <= MAX_VALUE ? totalSize : 0); + + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, aniProgressSize, aniTotalSize)) { + HILOGE("Create %{private}s object failed!", classDesc); + return nullptr; + } + return obj; +} + +void ProgressListenerAni::SendCopyProgress(uint64_t progressSize, uint64_t totalSize) const +{ + if (vm == nullptr) { + HILOGE("Cannot send copy progress because the vm is null."); + return; + } + if (listener == nullptr) { + HILOGE("Cannot send copy progress because the listener is null."); + return; + } + ani_env *env = AniHelper::GetThreadEnv(vm); + if (env == nullptr) { + HILOGE("Cannot send copy progress because the env is null."); + return; + } + auto evtObj = WrapCopyProgress(env, progressSize, totalSize); + if (evtObj == nullptr) { + HILOGE("Create copy progress obj failed!"); + return; + } + vector args = { static_cast(evtObj) }; + auto argc = args.size(); + ani_ref result; + auto cbObj = static_cast(listener); + auto status = env->FunctionalObject_Call(cbObj, argc, args.data(), &result); + if (status != ANI_OK) { + HILOGE("Failed to call FunctionalObject_Call, status: %{public}d", static_cast(status)); + return; + } +} + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h new file mode 100644 index 000000000..07894982a --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h @@ -0,0 +1,39 @@ +/* + * 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 INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_ANI_PROGRESS_LISTENER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_ANI_PROGRESS_LISTENER_H + +#include +#include +#include "i_progress_listener.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { + +class ProgressListenerAni final : public IProgressListener { +public: + ProgressListenerAni(ani_vm *vm, const ani_ref &listener) : vm(vm), listener(listener) {} + void InvokeListener(uint64_t progressSize, uint64_t totalSize) const override; + +private: + void SendCopyProgress(uint64_t progressSize, uint64_t totalSize) const; + +private: + ani_vm *vm; + ani_ref listener; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_ANI_PROGRESS_LISTENER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h similarity index 50% rename from interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity_core.cpp rename to interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h index 85dd60f91..f51f4f421 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/task_signal_entity_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 @@ -13,18 +13,19 @@ * limitations under the License. */ -#include "task_signal_entity_core.h" -#include "filemgmt_libhilog.h" +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H + +#include namespace OHOS::FileManagement::ModuleFileIO { -TaskSignalEntityCore::~TaskSignalEntityCore() {} +const uint64_t MAX_VALUE = 0x7FFFFFFFFFFFFFFF; + +class IProgressListener { +public: + virtual ~IProgressListener() = default; + virtual void InvokeListener(uint64_t progressSize, uint64_t totalSize) const = 0; +}; -void TaskSignalEntityCore::OnCancel() -{ - if (!callbackContextCore_) { - return; - } - - callbackContextCore_->cb(taskSignal_->filePath_); -} -} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp index 431a4f9e1..0b8d32b78 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -19,10 +19,10 @@ #include #include +#include "dfs_event_dfx.h" #include "ipc_skeleton.h" #include "sandbox_helper.h" #include "uri.h" -#include "dfs_event_dfx.h" #include "utils_log.h" namespace OHOS { @@ -70,22 +70,20 @@ int TransListenerCore::HandleCopyFailure(CopyEvent ©Event, const Storage::Di auto it = softbusErr2ErrCodeTable.find(copyEvent.errorCode); if (it == softbusErr2ErrCodeTable.end()) { RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, - RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, - RadarReporter::SEND_FILE_ERROR, RadarReporter::CONCURRENT_ID, currentId, - RadarReporter::PACKAGE_NAME, to_string(copyEvent.errorCode)); + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, RadarReporter::SEND_FILE_ERROR, + RadarReporter::CONCURRENT_ID, currentId, RadarReporter::PACKAGE_NAME, to_string(copyEvent.errorCode)); return EIO; } if (copyEvent.errorCode != DFS_CANCEL_SUCCESS) { HILOGE("HandleCopyFailure failed, copyEvent.errorCode = %{public}d.", copyEvent.errorCode); RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, - RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, - RadarReporter::SEND_FILE_ERROR, RadarReporter::CONCURRENT_ID, currentId, - RadarReporter::PACKAGE_NAME, to_string(copyEvent.errorCode)); + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, RadarReporter::SEND_FILE_ERROR, + RadarReporter::CONCURRENT_ID, currentId, RadarReporter::PACKAGE_NAME, to_string(copyEvent.errorCode)); } return it->second; } -int TransListenerCore::WaitForCopyResult(TransListenerCore* transListener) +int TransListenerCore::WaitForCopyResult(TransListenerCore *transListener) { if (transListener == nullptr) { HILOGE("transListener is nullptr"); @@ -93,14 +91,13 @@ int TransListenerCore::WaitForCopyResult(TransListenerCore* transListener) } std::unique_lock lock(transListener->cvMutex_); transListener->cv_.wait(lock, [&transListener]() { - return transListener->copyEvent_.copyResult == SUCCESS || - transListener->copyEvent_.copyResult == FAILED; + return transListener->copyEvent_.copyResult == SUCCESS || transListener->copyEvent_.copyResult == FAILED; }); return transListener->copyEvent_.copyResult; } int TransListenerCore::CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, - std::shared_ptr fileInfos, std::shared_ptr callback) + std::shared_ptr fileInfos, std::shared_ptr callback) { HILOGI("CopyFileFromSoftBus begin."); std::string currentId = "CopyFile_" + std::to_string(getpid()) + "_" + std::to_string(getSequenceId_); @@ -115,7 +112,7 @@ int TransListenerCore::CopyFileFromSoftBus(const std::string &srcUri, const std: } transListener->callback_ = std::move(callback); - Storage::DistributedFile::HmdfsInfo info{}; + Storage::DistributedFile::HmdfsInfo info {}; Uri uri(destUri); info.authority = uri.GetAuthority(); info.sandboxPath = SandboxHelper::Decode(uri.GetPath()); @@ -151,14 +148,11 @@ int TransListenerCore::CopyFileFromSoftBus(const std::string &srcUri, const std: return ERRNO_NOERR; } -int32_t TransListenerCore::PrepareCopySession(const std::string &srcUri, - const std::string &destUri, - TransListenerCore* transListener, - Storage::DistributedFile::HmdfsInfo &info, - std::string &disSandboxPath) +int32_t TransListenerCore::PrepareCopySession(const std::string &srcUri, const std::string &destUri, + TransListenerCore *transListener, Storage::DistributedFile::HmdfsInfo &info, std::string &disSandboxPath) { std::string tmpDir; - if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { + if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { tmpDir = CreateDfsCopyPath(); disSandboxPath = DISTRIBUTED_PATH + tmpDir; std::error_code errCode; @@ -181,8 +175,8 @@ int32_t TransListenerCore::PrepareCopySession(const std::string &srcUri, info.copyPath = tmpDir; auto networkId = GetNetworkIdFromUri(srcUri); HILOGI("dfs PrepareSession begin."); - auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession(srcUri, destUri, - networkId, transListener, info); + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession( + srcUri, destUri, networkId, transListener, info); if (ret != ERRNO_NOERR) { HILOGE("PrepareSession failed, ret = %{public}d.", ret); if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { @@ -218,8 +212,8 @@ int32_t TransListenerCore::CopyToSandBox(const std::string &srcUri, const std::s RmDir(disSandboxPath); return EIO; } - std::filesystem::copy(disSandboxPath + fileName, sandboxPath, std::filesystem::copy_options::update_existing, - errCode); + std::filesystem::copy( + disSandboxPath + fileName, sandboxPath, std::filesystem::copy_options::update_existing, errCode); if (errCode.value() != 0) { HILOGE("Copy file failed: errCode: %{public}d", errCode.value()); RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, @@ -250,14 +244,24 @@ std::string TransListenerCore::GetNetworkIdFromUri(const std::string &uri) return uri.substr(uri.find(NETWORK_PARA) + NETWORK_PARA.size(), uri.size()); } -void TransListenerCore::CallbackComplete(std::shared_ptr entry) +void TransListenerCore::CallbackComplete(std::shared_ptr entry) { if (entry == nullptr) { HILOGE("entry pointer is nullptr."); return; } - entry->callback->listenerCb(entry->progressSize, entry->totalSize); + if (entry->callback == nullptr) { + HILOGE("entry callback pointer is nullptr."); + return; + } + + auto listener = entry->callback->listener; + if (listener == nullptr) { + HILOGE("listener pointer is nullptr."); + return; + } + listener->InvokeListener(entry->progressSize, entry->totalSize); } int32_t TransListenerCore::OnFileReceive(uint64_t totalBytes, uint64_t processedBytes) @@ -268,7 +272,7 @@ int32_t TransListenerCore::OnFileReceive(uint64_t totalBytes, uint64_t processed return ENOMEM; } - std::shared_ptr entry = std::make_shared(callback_); + std::shared_ptr entry = std::make_shared(callback_); if (entry == nullptr) { HILOGE("entry ptr is nullptr"); return ENOMEM; diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h index d5b8f9585..c797454de 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef FILEMANAGEMENT_FILE_API_TRANS_LISTENER_CORE_H -#define FILEMANAGEMENT_FILE_API_TRANS_LISTENER_CORE_H +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H #include @@ -40,35 +40,31 @@ public: int32_t OnFileReceive(uint64_t totalBytes, uint64_t processedBytes) override; int32_t OnFinished(const std::string &sessionName) override; int32_t OnFailed(const std::string &sessionName, int32_t errorCode) override; - static int CopyFileFromSoftBus(const std::string &srcUri, - const std::string &destUri, - std::shared_ptr fileInfos, - std::shared_ptr callback); + static int CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + std::shared_ptr fileInfos, std::shared_ptr callback); + private: static std::string GetNetworkIdFromUri(const std::string &uri); - static void CallbackComplete(std::shared_ptr entry); + static void CallbackComplete(std::shared_ptr entry); static void RmDir(const std::string &path); static std::string CreateDfsCopyPath(); static std::string GetFileName(const std::string &path); static int32_t CopyToSandBox(const std::string &srcUri, const std::string &disSandboxPath, const std::string &sandboxPath, const std::string ¤tId); - static int32_t PrepareCopySession(const std::string &srcUri, - const std::string &destUri, - TransListenerCore* transListener, - Storage::DistributedFile::HmdfsInfo &info, - std::string &disSandboxPath); + static int32_t PrepareCopySession(const std::string &srcUri, const std::string &destUri, + TransListenerCore *transListener, Storage::DistributedFile::HmdfsInfo &info, std::string &disSandboxPath); static int HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, const std::string &disSandboxPath, const std::string ¤tId); - static int WaitForCopyResult(TransListenerCore* transListener); + static int WaitForCopyResult(TransListenerCore *transListener); static std::atomic getSequenceId_; std::mutex cvMutex_; std::condition_variable cv_; CopyEvent copyEvent_; std::mutex callbackMutex_; - std::shared_ptr callback_; + std::shared_ptr callback_; }; } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS -#endif // FILEMANAGEMENT_FILE_API_TRANS_LISTENER_CORE_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H \ No newline at end of file -- Gitee From ff5ae09233d9c40ad7601b5c10b492052e429e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9C=E5=B0=8F=E6=9E=97?= Date: Fri, 13 Jun 2025 09:49:18 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E6=84=8F=E8=A7=81=E8=BF=9B=E8=A1=8C=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1727413a28b67a39be892c644136f960df59590f Signed-off-by: 姜小林 --- .../kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets | 4 +++- .../ani/task_signal_listener_ani.cpp | 2 +- .../kits/js/src/mod_fs/properties/ani/copy_ani.cpp | 14 ++++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets index 1ebce3e37..610c1094f 100644 --- a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets +++ b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets @@ -1266,7 +1266,7 @@ export class TaskSignal { private native onCancelNative(): void; - private onCancelResolve: (path: string) => void; + private onCancelResolve: (path: string) => void = (path: string): void => {}; private onCancelCallback(path: string): void { if (this.onCancelResolve) { this.onCancelResolve(path); @@ -1282,6 +1282,8 @@ export class TaskSignal { this.onCancelNative(); } catch (e: BusinessError) { reject(e); + } catch (e: Error) { + reject(e as BusinessError); } }); } diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp index a80010e95..8f533889c 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.cpp @@ -55,7 +55,7 @@ void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const } auto ret = env->Object_CallMethodByName_Void(signalObj, "onCancelCallback", nullptr, aniPath); if (ret != ANI_OK) { - HILOGE("Call onCancelCallback failed, err: %{private}d", ret); + HILOGE("Call onCancelCallback failed, err: %{public}d", ret); return; } } diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp index 7e84bce8f..541cd7f6c 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp @@ -140,8 +140,18 @@ void CopyAni::CopySync( auto [succDest, dest] = TypeConverter::ToUTF8String(env, destUri); auto [succOpts, opts] = ParseOptions(env, options); - if (!succSrc || !succDest || !succOpts) { - HILOGE("The first/second/third argument requires uri/uri/napi_function"); + if (!succSrc) { + HILOGE("The first argument requires uri"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + if (!succDest) { + HILOGE("The second argument requires uri"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + if (!succOpts) { + HILOGE("The third argument requires listener function"); ErrorHandler::Throw(env, E_PARAMS); return; } -- Gitee From be85d044f846856655e5b348da4f343003d4c8a6 Mon Sep 17 00:00:00 2001 From: tianp Date: Mon, 16 Jun 2025 11:15:14 +0800 Subject: [PATCH 3/9] copyTDD Signed-off-by: tianp Change-Id: Ifaa8867aad18493f90a01787a1adff1252b7082f --- interfaces/test/unittest/js/BUILD.gn | 3 + .../js/mod_fs/properties/copy_core_test.cpp | 143 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index d8f84b8ef..99b819145 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -29,6 +29,7 @@ ohos_unittest("ani_file_fs_test") { "${file_api_path}/interfaces/kits/js/src/mod_fs/class_stream", "${file_api_path}/interfaces/kits/js/src/mod_fs/class_tasksignal", "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/copy_listener", ] sources = [ @@ -37,6 +38,7 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/class_stat/fs_stat_test.cpp", "mod_fs/class_stream/fs_stream_test.cpp", "mod_fs/properties/close_core_test.cpp", + "mod_fs/properties/copy_core_test.cpp", "mod_fs/properties/copy_dir_core_test.cpp", "mod_fs/properties/create_randomaccessfile_core_test.cpp", "mod_fs/properties/create_stream_core_test.cpp", @@ -44,6 +46,7 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/properties/listfile_core_test.cpp", "mod_fs/properties/lstat_core_test.cpp", "mod_fs/properties/open_core_test.cpp", + "mod_fs/properties/read_core_test.cpp", "mod_fs/properties/read_text_core_test.cpp", ] diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp new file mode 100644 index 000000000..0260100e9 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -0,0 +1,143 @@ +/* + * 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 "copy_core.h" + +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class CopyCoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void CopyCoreTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + int32_t fd = open("/data/test/src.txt", O_CREAT | O_RDWR, 0644); + close(fd); +} + +void CopyCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + rmdir("/data/test/CopyCoreTest.txt"); +} + +void CopyCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void CopyCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: CopyCoreTest_ValidParams_001 + * @tc.desc: Test function of CopyCore::ValidParams interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ValidParams_001"; + + string src = "invalid://data/test/src.txt"; + string dest = "file://data/test/dest.txt"; + + auto res = CopyCore::ValidParams(src, dest); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_001"; +} + +/** + * @tc.name: CopyCoreTest_ValidParams_002 + * @tc.desc: Test function of CopyCore::ValidParams interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ValidParams_002"; + + string src = "file://data/test/src.txt"; + string dest = "invalid://data/test/dest.txt"; + + auto res = CopyCore::ValidParams(src, dest); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_002"; +} + +/** + * @tc.name: CopyCoreTest_ValidParams_003 + * @tc.desc: Test function of CopyCore::ValidParams interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ValidParams_003"; + + string src = "file://data/test/src.txt"; + string dest = "file://data/test/dest.txt"; + + auto res = CopyCore::ValidParams(src, dest); + + EXPECT_EQ(res, true); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_003"; +} + +/** + * @tc.name: CopyCoreTest_CreateFileInfos_001 + * @tc.desc: Test function of CopyCore::CreateFileInfos interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CreateFileInfos_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CreateFileInfos_001"; + + string src = "file://data/test/src.txt"; + string dest = "file://data/test/dest.txt"; + optional options = std::make_optional(); + options->listener = std::make_shared(); + options-> + + + auto res = CopyCore::CreateFileInfos(src, dest, options); + + EXPECT_EQ(res, true); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CreateFileInfos_001"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file -- Gitee From d7e24b48c66dc43d213ad33caa4a9c4590af27f7 Mon Sep 17 00:00:00 2001 From: yangbiao59 Date: Tue, 17 Jun 2025 08:09:33 +0000 Subject: [PATCH 4/9] !1 add fs_task_signal_test.cpp * add tdd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib4c870ef0f2e3652ce3652adfacae59bc389fda9 Signed-off-by: 姜小林 --- interfaces/test/unittest/js/BUILD.gn | 2 + .../class_tasksignal/fs_task_signal_test.cpp | 203 ++++++++++++++++++ .../js/mod_fs/properties/copy_core_test.cpp | 48 ++--- 3 files changed, 229 insertions(+), 24 deletions(-) create mode 100644 interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index 99b819145..0ab2332b8 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -37,6 +37,8 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/class_randomaccessfile/fs_randomaccessfile_test.cpp", "mod_fs/class_stat/fs_stat_test.cpp", "mod_fs/class_stream/fs_stream_test.cpp", + "mod_fs/class_tasksignal/fs_task_signal_test.cpp", + "mod_fs/properties/access_core_test.cpp", "mod_fs/properties/close_core_test.cpp", "mod_fs/properties/copy_core_test.cpp", "mod_fs/properties/copy_dir_core_test.cpp", diff --git a/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp b/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp new file mode 100644 index 000000000..7a429951b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp @@ -0,0 +1,203 @@ +/* + * 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 "fs_task_signal.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class Assistant : public TaskSignalListener { +public: + void OnCancel() {} +}; + +class FsTaskSignalTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void FsTaskSignalTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FsTaskSignalTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FsTaskSignalTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void FsTaskSignalTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FsTaskSignalTest_Constructor_001 + * @tc.desc: Test function of FsTaskSignal::Constructor interface for False. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Constructor_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_Constructor_001"; + + FsTaskSignal fsTaskSignal; + shared_ptr taskSignal = nullptr; + shared_ptr signalListener = nullptr; + + auto res = fsTaskSignal.Constructor(taskSignal, signalListener); + + EXPECT_EQ(taskSignal, nullptr); + EXPECT_EQ(res.IsSuccess(), false); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_Constructor_001"; +} + +/** + * @tc.name: FsTaskSignalTest_Constructor_002 + * @tc.desc: Test function of FsTaskSignal::Constructor interface for False. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Constructor_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_Constructor_002"; + + FsTaskSignal fsTaskSignal; + shared_ptr taskSignal = std::make_shared(); + shared_ptr signalListener = nullptr; + + auto res = fsTaskSignal.Constructor(taskSignal, signalListener); + + EXPECT_NE(taskSignal, nullptr); + EXPECT_EQ(res.IsSuccess(), false); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_Constructor_002"; +} + +/** + * @tc.name: FsTaskSignalTest_Constructor_003 + * @tc.desc: Test function of FsTaskSignal::Constructor interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Constructor_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_Constructor_003"; + + FsTaskSignal fsTaskSignal; + shared_ptr taskSignal = std::make_shared(); + shared_ptr signalListener = std::make_shared(); + + auto res = fsTaskSignal.Constructor(taskSignal, signalListener); + + EXPECT_NE(signalListener, nullptr); + EXPECT_EQ(res.IsSuccess(), true); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_Constructor_003"; +} + +/** + * @tc.name: FsTaskSignalTest_Cancel_001 + * @tc.desc: Test function of FsTaskSignal::Cancel interface for false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Cancel_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_Cancel_001"; + + FsTaskSignal fsTaskSignal; + + auto res = fsTaskSignal.Cancel(); + + EXPECT_EQ(fsTaskSignal.taskSignal_, nullptr); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_Cancel_001"; +} + +/** + * @tc.name: FsTaskSignalTest_Cancel_002 + * @tc.desc: Test function of FsTaskSignal::Cancel interface for false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Cancel_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_Cancel_002"; + + FsTaskSignal fsTaskSignal; + fsTaskSignal.taskSignal_ = std::make_shared(); + + auto res = fsTaskSignal.Cancel(); + + EXPECT_NE(fsTaskSignal.taskSignal_, nullptr); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_Cancel_002"; +} + +/** + * @tc.name: FsTaskSignalTest_OnCancel_001 + * @tc.desc: Test function of FsTaskSignal::OnCancel interface for false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_OnCancel_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_OnCancel_001"; + + FsTaskSignal fsTaskSignal; + + auto res = fsTaskSignal.OnCancel(); + + EXPECT_EQ(fsTaskSignal.taskSignal_, nullptr); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_OnCancel_001"; +} + +/** + * @tc.name: FsTaskSignalTest_OnCancel_002 + * @tc.desc: Test function of FsTaskSignal::OnCancel interface for false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_OnCancel_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NClassTest-begin FsTaskSignalTest_OnCancel_002"; + + FsTaskSignal fsTaskSignal; + fsTaskSignal.taskSignal_ = std::make_shared(); + + auto res = fsTaskSignal.OnCancel(); + + EXPECT_NE(fsTaskSignal.taskSignal_, nullptr); + GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_OnCancel_002"; +} + +} // OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp index 0260100e9..7d20dac9e 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -115,29 +115,29 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_003, testing::ext::TestSize.Leve GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_003"; } -/** - * @tc.name: CopyCoreTest_CreateFileInfos_001 - * @tc.desc: Test function of CopyCore::CreateFileInfos interface for FALSE. - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 1 - */ -HWTEST_F(CopyCoreTest, CopyCoreTest_CreateFileInfos_001, testing::ext::TestSize.Level1) -{ - GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CreateFileInfos_001"; - - string src = "file://data/test/src.txt"; - string dest = "file://data/test/dest.txt"; - optional options = std::make_optional(); - options->listener = std::make_shared(); - options-> - - - auto res = CopyCore::CreateFileInfos(src, dest, options); - - EXPECT_EQ(res, true); - - GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CreateFileInfos_001"; -} +// /** +// * @tc.name: CopyCoreTest_CreateFileInfos_001 +// * @tc.desc: Test function of CopyCore::CreateFileInfos interface for FALSE. +// * @tc.size: MEDIUM +// * @tc.type: FUNC +// * @tc.level Level 1 +// */ +// HWTEST_F(CopyCoreTest, CopyCoreTest_CreateFileInfos_001, testing::ext::TestSize.Level1) +// { +// GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CreateFileInfos_001"; + +// string src = "file://data/test/src.txt"; +// string dest = "file://data/test/dest.txt"; +// optional options = std::make_optional(); +// options->listener = std::make_shared(); +// options-> + + +// auto res = CopyCore::CreateFileInfos(src, dest, options); + +// EXPECT_EQ(res, true); + +// GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CreateFileInfos_001"; +// } } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file -- Gitee From cbbf3d7fb442a73e5bee033102cb05cf713c36b4 Mon Sep 17 00:00:00 2001 From: tianp Date: Tue, 17 Jun 2025 16:41:36 +0800 Subject: [PATCH 5/9] =?UTF-8?q?copyTDD=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tianp Change-Id: I1aef1625484f6c1c18a1d8b8202c03872e13457d --- .../js/mod_fs/properties/copy_core_test.cpp | 541 +++++++++++++++++- 1 file changed, 512 insertions(+), 29 deletions(-) diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp index 7d20dac9e..088817b9c 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -16,6 +16,7 @@ #include "copy_core.h" #include +#include #include namespace OHOS::FileManagement::ModuleFileIO::Test { @@ -29,19 +30,39 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); + + static const string testDir; + static const string srcDir; + static const string destDir; + static const string srcFile; + static const string destFile; }; +const string CopyCoreTest::testDir = "/data/test"; +const string CopyCoreTest::srcDir = testDir + "/src"; +const string CopyCoreTest::destDir = testDir + "/dest"; +const string CopyCoreTest::srcFile = srcDir + "/src.txt"; +const string CopyCoreTest::destFile = destDir + "/dest.txt"; + void CopyCoreTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; - int32_t fd = open("/data/test/src.txt", O_CREAT | O_RDWR, 0644); - close(fd); + mkdir(testDir.c_str(), 0755); + mkdir(srcDir.c_str(), 0755); + mkdir(destDir.c_str(), 0755); + int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } } void CopyCoreTest::TearDownTestCase(void) { GTEST_LOG_(INFO) << "TearDownTestCase"; - rmdir("/data/test/CopyCoreTest.txt"); + remove(srcFile.c_str()); + rmdir(srcDir.c_str()); + rmdir(destDir.c_str()); + rmdir(testDir.c_str()); } void CopyCoreTest::SetUp(void) @@ -52,6 +73,275 @@ void CopyCoreTest::SetUp(void) void CopyCoreTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; + remove(destFile.c_str()); +} + +/** + * @tc.name: CopyCoreTest_IsValidUri_001 + * @tc.desc: Test function of CopyCore::IsValidUri interface for TRUE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsValidUri_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsValidUri_001"; + + string validUri = "file://data/test/file.txt"; + auto res = CopyCore::IsValidUri(validUri); + EXPECT_EQ(res, true); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsValidUri_001"; +} + +/** + * @tc.name: CopyCoreTest_IsValidUri_002 + * @tc.desc: Test function of CopyCore::IsValidUri interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsValidUri_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsValidUri_002"; + + string invalidUri = "invalid://data/test/file.txt"; + auto res = CopyCore::IsValidUri(invalidUri); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsValidUri_002"; +} + +/** + * @tc.name: CopyCoreTest_IsRemoteUri_001 + * @tc.desc: Test function of CopyCore::IsRemoteUri interface for TRUE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsRemoteUri_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsRemoteUri_001"; + + string remoteUri = "file://data/test/file.txt?networkid=123"; + auto res = CopyCore::IsRemoteUri(remoteUri); + EXPECT_EQ(res, true); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsRemoteUri_001"; +} + +/** + * @tc.name: CopyCoreTest_IsRemoteUri_002 + * @tc.desc: Test function of CopyCore::IsRemoteUri interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsRemoteUri_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsRemoteUri_002"; + + string localUri = "file://data/test/file.txt"; + auto res = CopyCore::IsRemoteUri(localUri); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsRemoteUri_002"; +} + +/** + * @tc.name: CopyCoreTest_IsDirectory_001 + * @tc.desc: Test function of CopyCore::IsDirectory interface for TRUE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsDirectory_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsDirectory_001"; + + auto res = CopyCore::IsDirectory(srcDir); + EXPECT_EQ(res, true); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsDirectory_001"; +} + +/** + * @tc.name: CopyCoreTest_IsDirectory_002 + * @tc.desc: Test function of CopyCore::IsDirectory interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsDirectory_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsDirectory_002"; + + auto res = CopyCore::IsDirectory(srcFile); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsDirectory_002"; +} + +/** + * @tc.name: CopyCoreTest_IsFile_001 + * @tc.desc: Test function of CopyCore::IsFile interface for TRUE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsFile_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsFile_001"; + + auto res = CopyCore::IsFile(srcFile); + EXPECT_EQ(res, true); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsFile_001"; +} + +/** + * @tc.name: CopyCoreTest_IsFile_002 + * @tc.desc: Test function of CopyCore::IsFile interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsFile_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsFile_002"; + + auto res = CopyCore::IsFile(srcDir); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsFile_002"; +} + +/** + * @tc.name: CopyCoreTest_GetFileSize_001 + * @tc.desc: Test function of CopyCore::GetFileSize interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetFileSize_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetFileSize_001"; + + auto [err, size] = CopyCore::GetFileSize(srcFile); + EXPECT_EQ(err, ERRNO_NOERR); + EXPECT_GE(size, 0); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetFileSize_001"; +} + +/** + * @tc.name: CopyCoreTest_GetFileSize_002 + * @tc.desc: Test function of CopyCore::GetFileSize interface for failure. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetFileSize_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetFileSize_002"; + + string nonExistentFile = "/data/test/non_existent.txt"; + auto [err, size] = CopyCore::GetFileSize(nonExistentFile); + EXPECT_NE(err, ERRNO_NOERR); + EXPECT_EQ(size, 0); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetFileSize_002"; +} + +/** + * @tc.name: CopyCoreTest_CheckOrCreatePath_001 + * @tc.desc: Test function of CopyCore::CheckOrCreatePath interface for existing file. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CheckOrCreatePath_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CheckOrCreatePath_001"; + + auto res = CopyCore::CheckOrCreatePath(srcFile); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CheckOrCreatePath_001"; +} + +/** + * @tc.name: CopyCoreTest_CheckOrCreatePath_002 + * @tc.desc: Test function of CopyCore::CheckOrCreatePath interface for creating new file. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CheckOrCreatePath_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CheckOrCreatePath_002"; + + string newFile = destDir + "/new_file.txt"; + auto res = CopyCore::CheckOrCreatePath(newFile); + EXPECT_EQ(res, ERRNO_NOERR); + EXPECT_TRUE(CopyCore::IsFile(newFile)); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CheckOrCreatePath_002"; +} + +/** + * @tc.name: CopyCoreTest_MakeDir_001 + * @tc.desc: Test function of CopyCore::MakeDir interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_MakeDir_001"; + + string newDir = destDir + "/new_dir"; + auto res = CopyCore::MakeDir(newDir); + EXPECT_EQ(res, ERRNO_NOERR); + EXPECT_TRUE(CopyCore::IsDirectory(newDir)); + + rmdir(newDir.c_str()); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_MakeDir_001"; +} + +/** + * @tc.name: CopyCoreTest_MakeDir_002 + * @tc.desc: Test function of CopyCore::MakeDir interface for existing directory. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 2 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_MakeDir_002"; + + auto res = CopyCore::MakeDir(srcDir); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_MakeDir_002"; +} + +/** + * @tc.name: CopyCoreTest_MakeDir_003 + * @tc.desc: Test function of CopyCore::MakeDir interface for invalid path. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 2 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_MakeDir_003"; + + string invalidPath = "/invalid/path/dir"; + auto res = CopyCore::MakeDir(invalidPath); + EXPECT_NE(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_MakeDir_003"; } /** @@ -65,10 +355,9 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_001, testing::ext::TestSize.Leve { GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ValidParams_001"; - string src = "invalid://data/test/src.txt"; - string dest = "file://data/test/dest.txt"; + string srcFile = "invalid://data/test/src.txt"; - auto res = CopyCore::ValidParams(src, dest); + auto res = CopyCore::ValidParams(srcFile, destFile); EXPECT_EQ(res, false); GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_001"; @@ -85,10 +374,9 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_002, testing::ext::TestSize.Leve { GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ValidParams_002"; - string src = "file://data/test/src.txt"; - string dest = "invalid://data/test/dest.txt"; + string destFile = "invalid://data/test/dest.txt"; - auto res = CopyCore::ValidParams(src, dest); + auto res = CopyCore::ValidParams(srcFile, destFile); EXPECT_EQ(res, false); GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_002"; @@ -109,35 +397,230 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ValidParams_003, testing::ext::TestSize.Leve string dest = "file://data/test/dest.txt"; auto res = CopyCore::ValidParams(src, dest); - EXPECT_EQ(res, true); GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ValidParams_003"; } -// /** -// * @tc.name: CopyCoreTest_CreateFileInfos_001 -// * @tc.desc: Test function of CopyCore::CreateFileInfos interface for FALSE. -// * @tc.size: MEDIUM -// * @tc.type: FUNC -// * @tc.level Level 1 -// */ -// HWTEST_F(CopyCoreTest, CopyCoreTest_CreateFileInfos_001, testing::ext::TestSize.Level1) -// { -// GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CreateFileInfos_001"; +/** + * @tc.name: CopyCoreTest_CreateFileInfos_001 + * @tc.desc: Test function of CopyCore::CreateFileInfos interface for TRUE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CreateFileInfos_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CreateFileInfos_001"; + + optional options = std::make_optional(); -// string src = "file://data/test/src.txt"; -// string dest = "file://data/test/dest.txt"; -// optional options = std::make_optional(); -// options->listener = std::make_shared(); -// options-> + auto [errCode, infos] = CopyCore::CreateFileInfos(srcFile, destFile, options); + EXPECT_EQ(errCode, ERRNO_NOERR); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CreateFileInfos_001"; +} + +/** + * @tc.name: CopyCoreTest_CopySubDir_001 + * @tc.desc: Test function of CopyCore::CopySubDir interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopySubDir_001"; -// auto res = CopyCore::CreateFileInfos(src, dest, options); + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), 0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } -// EXPECT_EQ(res, true); + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + auto res = CopyCore::CopySubDir(subDir, destSubDir, infos); + string destSubFile = destSubDir + "/sub_file.txt"; + EXPECT_EQ(res, ERRNO_NOERR); + EXPECT_TRUE(CopyCore::IsDirectory(destSubDir)); + EXPECT_TRUE(CopyCore::IsFile(destSubFile)); -// GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CreateFileInfos_001"; -// } + remove(subFile.c_str()); + rmdir(subDir.c_str()); + remove(destSubFile.c_str()); + rmdir(destSubDir.c_str()); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CopySubDir_001"; +} + +/** + * @tc.name: CopyCoreTest_RecurCopyDir_001 + * @tc.desc: Test function of CopyCore::RecurCopyDir interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_RecurCopyDir_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_RecurCopyDir_001"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), 0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } + + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + auto res = CopyCore::RecurCopyDir(srcDir, destDir, infos); + string destSubFile = destSubDir + "/sub_file.txt"; + EXPECT_EQ(res, ERRNO_NOERR); + EXPECT_TRUE(CopyCore::IsDirectory(destSubDir)); + EXPECT_TRUE(CopyCore::IsFile(destSubDir + "/sub_file.txt")); + + remove(subFile.c_str()); + rmdir(subDir.c_str()); + remove(destSubFile.c_str()); + rmdir(destSubDir.c_str()); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_RecurCopyDir_001"; +} + +/** + * @tc.name: CopyCoreTest_CopyDirFunc_001 + * @tc.desc: Test function of CopyCore::CopyDirFunc interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CopyDirFunc_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopyDirFunc_001"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), 0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } + + string destSubDir = destDir + "/src/sub_dir"; + string destSubFile = destSubDir + "/sub_file.txt"; + string destSrcDir = destDir + "/src"; + auto infos = make_shared(); + auto res = CopyCore::CopyDirFunc(srcDir, destDir, infos); + EXPECT_EQ(res, ERRNO_NOERR); + EXPECT_EQ(CopyCore::IsDirectory(destSubDir), false); + EXPECT_EQ(CopyCore::IsFile(destSubDir + "/sub_file.txt"), false); + + remove(subFile.c_str()); + rmdir(subDir.c_str()); + remove(destSubFile.c_str()); + rmdir(destSubDir.c_str()); + rmdir(destSrcDir.c_str()); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CopyDirFunc_001"; +} + +/** + * @tc.name: CopyCoreTest_ExecLocal_001 + * @tc.desc: Test function of CopyCore::ExecLocal interface for file copy success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_ExecLocal_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ExecLocal_001"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = srcFile; + infos->destPath = destFile; + + auto callback = make_shared(nullptr); + auto res = CopyCore::ExecLocal(infos, callback); + EXPECT_EQ(res, ERRNO_NOERR); + EXPECT_TRUE(CopyCore::IsFile(destFile)); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ExecLocal_001"; +} + +/** + * @tc.name: CopyCoreTest_RegisterListener_001 + * @tc.desc: Test function of CopyCore::RegisterListener interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_RegisterListener_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_RegisterListener_001"; + + auto infos = make_shared(); + auto callback = CopyCore::RegisterListener(infos); + EXPECT_NE(callback, nullptr); + + { + std::lock_guard lock(CopyCore::mutex_); + auto iter = CopyCore::callbackMap_.find(*infos); + EXPECT_NE(iter, CopyCore::callbackMap_.end()); + } + + CopyCore::UnregisterListener(infos); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_RegisterListener_001"; +} + +/** + * @tc.name: CopyCoreTest_UnregisterListener_001 + * @tc.desc: Test function of CopyCore::UnregisterListener interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_UnregisterListener_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_UnregisterListener_001"; + + auto infos = make_shared(); + auto callback = CopyCore::RegisterListener(infos); + EXPECT_NE(callback, nullptr); + + CopyCore::UnregisterListener(infos); + + { + std::lock_guard lock(CopyCore::mutex_); + auto iter = CopyCore::callbackMap_.find(*infos); + EXPECT_EQ(iter, CopyCore::callbackMap_.end()); + } + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_UnregisterListener_001"; +} + +/** + * @tc.name: CopyCoreTest_DoCopy_001 + * @tc.desc: Test function of CopyCore::DoCopy interface for failure (invalid params). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_DoCopy_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_DoCopy_001"; + + string src = "invalid:/" + srcFile; + string dest = "invalid:/" + destFile; + optional options; + + auto res = CopyCore::DoCopy(src, dest, options); + EXPECT_FALSE(res.IsSuccess()); + auto err = res.GetError(); + EXPECT_EQ(err.GetErrNo(), E_PARAMS); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_DoCopy_001"; +} } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file -- Gitee From 7ff91a2f1a8947af450e2e3ec7028ee51c687136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E9=91=AB?= Date: Tue, 17 Jun 2025 11:18:35 +0000 Subject: [PATCH 6/9] !2 tdd + 3 tdd + 4 0619 * tdd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6b56e0d9f19df7f43ea97b392e9c3a2e85d57978 Signed-off-by: 周鑫 --- interfaces/test/unittest/js/BUILD.gn | 13 + .../properties/trans_listener_mock_test.cpp | 229 +++++++ .../mod_fs/properties/trans_listener_test.cpp | 610 ++++++++++++++++++ 3 files changed, 852 insertions(+) create mode 100644 interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index 0ab2332b8..e32056d7e 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -50,6 +50,11 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/properties/open_core_test.cpp", "mod_fs/properties/read_core_test.cpp", "mod_fs/properties/read_text_core_test.cpp", + "mod_fs/properties/rmdir_core_test.cpp", + "mod_fs/properties/trans_listener_test.cpp", + "mod_fs/properties/truncate_core_test.cpp", + "mod_fs/properties/utimes_core_test.cpp", + "mod_fs/properties/write_core_test.cpp", ] deps = [ @@ -65,6 +70,8 @@ ohos_unittest("ani_file_fs_test") { "ability_runtime:ability_manager", "app_file_service:fileuri_native", "c_utils:utils", + "dfs_service:distributed_file_daemon_kit_inner", + "dfs_service:libdistributedfileutils", "googletest:gtest_main", "hilog:libhilog", "ipc:ipc_core", @@ -101,10 +108,16 @@ ohos_unittest("ani_file_fs_mock_test") { "mod_fs/class_stream/fs_stream_mock_test.cpp", "mod_fs/class_stream/mock/c_mock.cpp", "mod_fs/properties/create_randomaccessfile_core_mock_test.cpp", + "mod_fs/properties/dup_core_mock_test.cpp", "mod_fs/properties/lstat_core_mock_test.cpp", "mod_fs/properties/mock/system_mock.cpp", "mod_fs/properties/mock/uv_fs_mock.cpp", "mod_fs/properties/open_core_mock_test.cpp", + "mod_fs/properties/read_core_mock_test.cpp", + "mod_fs/properties/symlink_core_mock_test.cpp", + "mod_fs/properties/trans_listener_mock_test.cpp", + "mod_fs/properties/truncate_core_mock_test.cpp", + "mod_fs/properties/utimes_core_mock_test.cpp", ] deps = [ diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp new file mode 100644 index 000000000..56c11d8b5 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp @@ -0,0 +1,229 @@ +/* + * 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 "trans_listener_core.h" + +#include +#include +#include + +#include "copy_core.h" + +using namespace OHOS; +using namespace OHOS::Storage::DistributedFile; + +class MockDistributedFileDaemonManager : public DistributedFileDaemonManager { +public: + MOCK_METHOD(int32_t, CancelCopyTask, (const std::string &sessionName), (override)); + + int32_t OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override + { + return 0; + } + + int32_t CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override + { + return 0; + } + + int32_t OpenP2PConnectionEx(const std::string &networkId, sptr remoteReverseObj) override + { + return 0; + } + + int32_t CloseP2PConnectionEx(const std::string &networkId) override + { + return 0; + } + + // int32_t PrepareSession(const std::string &srcUri, const std::string &dstUri, const std::string &srcDeviceId, + // const sptr &listener, HmdfsInfo &info) override + // { + // return 0; + // } + MOCK_METHOD(int32_t, PrepareSession, (const std::string &srcUri, const std::string &dstUri, + const std::string &srcDeviceId, + const sptr &listener, HmdfsInfo &info), (override)); + + int32_t PushAsset( + int32_t userId, const sptr &assetObj, const sptr &sendCallback) override + { + return 0; + } + + int32_t RegisterAssetCallback(const sptr &recvCallback) override + { + return 0; + } + + int32_t UnRegisterAssetCallback(const sptr &recvCallback) override + { + return 0; + } + + int32_t GetSize(const std::string &uri, bool isSrcUri, uint64_t &size) override + { + return 0; + } + + int32_t IsDirectory(const std::string &uri, bool isSrcUri, bool &isDirectory) override + { + return 0; + } + + int32_t Copy(const std::string &srcUri, const std::string &destUri, ProcessCallback processCallback) override + { + return 0; + } + + int32_t Cancel(const std::string &srcUri, const std::string &destUri) override + { + return 0; + } + + int32_t Cancel() override + { + return 0; + } + + static MockDistributedFileDaemonManager &GetInstance() + { + static MockDistributedFileDaemonManager instance; + return instance; + } +}; + +static MockDistributedFileDaemonManager &g_mockDistributedFileDaemonManager = + MockDistributedFileDaemonManager::GetInstance(); + +#ifdef ENABLE_DISTRIBUTED_FILE_MOCK +DistributedFileDaemonManager &DistributedFileDaemonManager::GetInstance() +{ + return MockDistributedFileDaemonManager::GetInstance(); +} +#endif + +class MockTaskSignalListener : public OHOS::DistributedFS::ModuleTaskSignal::TaskSignalListener { +public: + MOCK_METHOD(void, OnCancel, (), (override)); +}; + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +string g_path = "/data/test/TransListenerCoreTest.txt"; +const string FILE_MANAGER_AUTHORITY = "docs"; +const string MEDIA_AUTHORITY = "media"; + +class IProgressListenerTest : public IProgressListener { +public: + void InvokeListener(uint64_t progressSize, uint64_t totalSize) const override {} +}; + +class TransListenerCoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + MockDistributedFileDaemonManager &GetMock() + { + return g_mockDistributedFileDaemonManager; + } +}; + +void TransListenerCoreTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + int32_t fd = open(g_path.c_str(), O_CREAT | O_RDWR, 0644); + close(fd); +} + +void TransListenerCoreTest::TearDownTestCase(void) +{ + rmdir(g_path.c_str()); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void TransListenerCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void TransListenerCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: TransListenerCoreTest_PrepareCopySession_001 + * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_001"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = FILE_MANAGER_AUTHORITY; + info.authority = MEDIA_AUTHORITY; + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + string disSandboxPath = "disSandboxPath"; + + EXPECT_CALL(GetMock(), PrepareSession(testing::_, testing::_, testing::_, testing::_, testing::_)) + .WillOnce(testing::Return(ERRNO_NOERR)); + auto result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); + EXPECT_EQ(result, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_001"; +} + +/** + * @tc.name: TransListenerCoreTest_CopyFileFromSoftBus_001 + * @tc.desc: Test function of TransListenerCore::CopyFileFromSoftBus interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CopyFileFromSoftBus_001"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = FILE_MANAGER_AUTHORITY; + + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + shared_ptr transListener(new TransListenerCore); + std::shared_ptr infos(new FsFileInfos); + // transListener->copyEvent_.copyResult = FAILED; + + // shared_ptr transListenerArg(new TransListenerCore); + // transListenerArg->copyEvent_.errorCode = DFS_CANCEL_SUCCESS; + + EXPECT_CALL(GetMock(), PrepareSession(testing::_, testing::_, testing::_, testing::_, testing::_)) + .WillOnce(testing::Return(ERRNO_NOERR)); + + auto res = transListener->CopyFileFromSoftBus(srcUri, "destUri", infos, nullptr); + EXPECT_EQ(res, EIO); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CopyFileFromSoftBus_001"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp new file mode 100644 index 000000000..b1a727d4e --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp @@ -0,0 +1,610 @@ +/* + * 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 "trans_listener_core.h" + +#include +#include + +#include "copy_core.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +string g_path = "/data/test/TransListenerCoreTest.txt"; +const string FILE_MANAGER_AUTHORITY = "docs"; +const string MEDIA_AUTHORITY = "media"; + +class IProgressListenerTest : public IProgressListener { +public: + void InvokeListener(uint64_t progressSize, uint64_t totalSize) const override {} +}; + +class TransListenerCoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void TransListenerCoreTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + int32_t fd = open(g_path.c_str(), O_CREAT | O_RDWR, 0644); + close(fd); +} + +void TransListenerCoreTest::TearDownTestCase(void) +{ + rmdir(g_path.c_str()); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void TransListenerCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void TransListenerCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +// /** +// * @tc.name: TransListenerCoreTest_RmDir_001 +// * @tc.desc: Test function of TransListenerCore::RmDir interface for FALSE. +// * @tc.size: MEDIUM +// * @tc.type: FUNC +// * @tc.level Level 1 +// */ +// HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_RmDir_001, testing::ext::TestSize.Level1) +// { +// GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_RmDir_001"; + +// string path = "/data/test/TransListenerCoreTest_RmDir_001.txt"; + +// TransListenerCore::RmDir(path); + +// GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_RmDir_001"; +// } + +// /** +// * @tc.name: TransListenerCoreTest_RmDir_002 +// * @tc.desc: Test function of TransListenerCore::RmDir interface for SUCC. +// * @tc.size: MEDIUM +// * @tc.type: FUNC +// * @tc.level Level 1 +// */ +// HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_RmDir_002, testing::ext::TestSize.Level1) +// { +// GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_RmDir_002"; + +// string path = "/data/test/TransListenerCoreTest_RmDir_002.txt"; +// int32_t fd = open(path, O_CREAT | O_RDWR, 0644); +// close(fd); + +// TransListenerCore::RmDir(path); + +// GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_RmDir_002"; +// } + +/** + * @tc.name: TransListenerCoreTest_CreateDfsCopyPath_001 + * @tc.desc: Test function of TransListenerCore::CreateDfsCopyPath interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CreateDfsCopyPath_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CreateDfsCopyPath_001"; + + string result = TransListenerCore::CreateDfsCopyPath(); + EXPECT_EQ(result, "/data/storage/el2/distributedfiles/"); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CreateDfsCopyPath_001"; +} + +/** + * @tc.name: TransListenerCoreTest_HandleCopyFailure_001 + * @tc.desc: Test function of TransListenerCore::HandleCopyFailure interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_HandleCopyFailure_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_HandleCopyFailure_001"; + + string path = "/data/test/TransListenerCoreTest_HandleCopyFailure_001.txt"; + Storage::DistributedFile::HmdfsInfo info; + info.authority = "abc"; + CopyEvent event; + event.errorCode = 0; + int result = TransListenerCore::HandleCopyFailure(event, info, path, ""); + EXPECT_EQ(result, EIO); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_HandleCopyFailure_001"; +} + +/** + * @tc.name: TransListenerCoreTest_HandleCopyFailure_002 + * @tc.desc: Test function of TransListenerCore::HandleCopyFailure interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_HandleCopyFailure_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_HandleCopyFailure_002"; + + string path = "/data/test/TransListenerCoreTest_HandleCopyFailure_002.txt"; + int32_t fd = open(path.c_str(), O_CREAT | O_RDWR, 0644); + close(fd); + + Storage::DistributedFile::HmdfsInfo info; + info.authority = "abc"; + CopyEvent event; + event.errorCode = SOFTBUS_TRANS_FILE_EXISTED; + int result = TransListenerCore::HandleCopyFailure(event, info, path, ""); + EXPECT_EQ(result, EEXIST); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_HandleCopyFailure_002"; +} + +/** + * @tc.name: TransListenerCoreTest_HandleCopyFailure_003 + * @tc.desc: Test function of TransListenerCore::HandleCopyFailure interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_HandleCopyFailure_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_HandleCopyFailure_003"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = MEDIA_AUTHORITY; + CopyEvent event; + event.errorCode = DFS_CANCEL_SUCCESS; + int result = TransListenerCore::HandleCopyFailure(event, info, "", ""); + EXPECT_EQ(result, ECANCELED); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_HandleCopyFailure_003"; +} + +/** + * @tc.name: TransListenerCoreTest_WaitForCopyResult_001 + * @tc.desc: Test function of TransListenerCore::WaitForCopyResult interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_WaitForCopyResult_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_WaitForCopyResult_001"; + + shared_ptr transListener(new TransListenerCore); + transListener->copyEvent_.copyResult = FAILED; + int result = TransListenerCore::WaitForCopyResult(transListener.get()); + EXPECT_EQ(result, 2); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_WaitForCopyResult_001"; +} + +/** + * @tc.name: TransListenerCoreTest_WaitForCopyResult_002 + * @tc.desc: Test function of TransListenerCore::WaitForCopyResult interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_WaitForCopyResult_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_WaitForCopyResult_002"; + + int result = TransListenerCore::WaitForCopyResult(nullptr); + EXPECT_TRUE(result); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_WaitForCopyResult_002"; +} + +/** + * @tc.name: TransListenerCoreTest_PrepareCopySession_001 + * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_001"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = MEDIA_AUTHORITY; + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + string disSandboxPath = "disSandboxPath"; + + int result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); + EXPECT_EQ(result, EIO); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_001"; +} + +/** + * @tc.name: TransListenerCoreTest_PrepareCopySession_002 + * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_002"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = "abc"; + + string disSandboxPath = "disSandboxPath"; + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + int result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); + EXPECT_EQ(result, ENOENT); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_002"; +} + +/** + * @tc.name: TransListenerCoreTest_PrepareCopySession_003 + * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_003"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = "abc"; + info.sandboxPath = "abc"; + + string disSandboxPath = "disSandboxPath"; + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + int result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); + EXPECT_EQ(result, ENOENT); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_003"; +} + +/** + * @tc.name: TransListenerCoreTest_PrepareCopySession_004 + * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_004"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = "abc"; + info.sandboxPath = "/data/test/PrepareCopySession_004.txt"; + + string disSandboxPath = "disSandboxPath"; + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + int result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); + EXPECT_EQ(result, ENOENT); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_004"; +} + +/** + * @tc.name: TransListenerCoreTest_PrepareCopySession_005 + * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_005"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = "abc"; + info.sandboxPath = "/data/test/PrepareCopySession_004.txt"; + int32_t fd = open(info.sandboxPath.c_str(), O_CREAT | O_RDWR, 0644); + close(fd); + + string disSandboxPath = "disSandboxPath"; + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + int result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); + EXPECT_EQ(result, ENOENT); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_005"; +} + +/** + * @tc.name: TransListenerCoreTest_CopyToSandBox_001 + * @tc.desc: Test function of TransListenerCore::CopyToSandBox interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyToSandBox_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CopyToSandBox_001"; + + string disSandboxPath = "disSandboxPath"; + string sandboxPath = "sandboxPath"; + string currentId = "currentId"; + + int result = TransListenerCore::CopyToSandBox("srcUri", disSandboxPath, sandboxPath, currentId); + EXPECT_EQ(result, EIO); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CopyToSandBox_001"; +} + +/** + * @tc.name: TransListenerCoreTest_CopyToSandBox_002 + * @tc.desc: Test function of TransListenerCore::CopyToSandBox interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyToSandBox_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CopyToSandBox_002"; + + string disSandboxPath = g_path; + string sandboxPath = "/data/test"; + string currentId = "currentId"; + + int result = TransListenerCore::CopyToSandBox("srcUri", disSandboxPath, sandboxPath, currentId); + EXPECT_EQ(result, EIO); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CopyToSandBox_002"; +} + +/** + * @tc.name: TransListenerCoreTest_GetFileName_001 + * @tc.desc: Test function of TransListenerCore::GetFileName interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_GetFileName_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_GetFileName_001"; + + string path = "abc"; + + auto result = TransListenerCore::GetFileName(path); + EXPECT_EQ(result, ""); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_GetFileName_001"; +} + +/** + * @tc.name: TransListenerCoreTest_GetFileName_002 + * @tc.desc: Test function of TransListenerCore::GetFileName interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_GetFileName_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_GetFileName_002"; + + auto result = TransListenerCore::GetFileName(g_path); + EXPECT_EQ(result, "/TransListenerCoreTest.txt"); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_GetFileName_002"; +} + +/** + * @tc.name: TransListenerCoreTest_GetNetworkIdFromUri_001 + * @tc.desc: Test function of TransListenerCore::GetNetworkIdFromUri interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_GetNetworkIdFromUri_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_GetNetworkIdFromUri_001"; + + string uri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + + auto result = TransListenerCore::GetNetworkIdFromUri(uri); + EXPECT_EQ(result, "AD125AD1CF"); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_GetNetworkIdFromUri_001"; +} + +/** + * @tc.name: TransListenerCoreTest_CallbackComplete_001 + * @tc.desc: Test function of TransListenerCore::CallbackComplete interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CallbackComplete_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CallbackComplete_001"; + + TransListenerCore::CallbackComplete(nullptr); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CallbackComplete_001"; +} + +/** + * @tc.name: TransListenerCoreTest_CallbackComplete_002 + * @tc.desc: Test function of TransListenerCore::CallbackComplete interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CallbackComplete_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CallbackComplete_002"; + + auto entry = make_shared(make_shared(std::make_shared())); + entry->callback = nullptr; + TransListenerCore::CallbackComplete(entry); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CallbackComplete_002"; +} + +/** + * @tc.name: TransListenerCoreTest_CallbackComplete_003 + * @tc.desc: Test function of TransListenerCore::CallbackComplete interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CallbackComplete_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CallbackComplete_003"; + + auto entry = make_shared(make_shared(std::make_shared())); + entry->callback->listener = nullptr; + TransListenerCore::CallbackComplete(entry); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CallbackComplete_003"; +} + +/** + * @tc.name: TransListenerCoreTest_CallbackComplete_004 + * @tc.desc: Test function of TransListenerCore::CallbackComplete interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CallbackComplete_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CallbackComplete_004"; + + auto entry = make_shared(make_shared(std::make_shared())); + TransListenerCore::CallbackComplete(entry); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CallbackComplete_004"; +} + +/** + * @tc.name: TransListenerCoreTest_OnFileReceive_001 + * @tc.desc: Test function of TransListenerCore::OnFileReceive interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFileReceive_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFileReceive_001"; + + shared_ptr transListener(new TransListenerCore); + transListener->callback_ = nullptr; + auto res = transListener->OnFileReceive(0, 0); + EXPECT_EQ(res, ENOMEM); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_OnFileReceive_001"; +} + +/** + * @tc.name: TransListenerCoreTest_OnFileReceive_002 + * @tc.desc: Test function of TransListenerCore::OnFileReceive interface for SUCC. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFileReceive_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFileReceive_002"; + + shared_ptr transListener(new TransListenerCore); + transListener->callback_ = make_shared(std::make_shared()); + auto res = transListener->OnFileReceive(0, 0); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_OnFileReceive_002"; +} + +/** + * @tc.name: TransListenerCoreTest_OnFinished_001 + * @tc.desc: Test function of TransListenerCore::OnFinished interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFinished_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFinished_001"; + + shared_ptr transListener(new TransListenerCore); + auto res = transListener->OnFinished("sessionName"); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_OnFinished_001"; +} + +/** + * @tc.name: TransListenerCoreTest_OnFailed_001 + * @tc.desc: Test function of TransListenerCore::OnFailed interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFailed_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFailed_001"; + + shared_ptr transListener(new TransListenerCore); + auto res = transListener->OnFailed("sessionName", 0); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_OnFailed_001"; +} + +/** + * @tc.name: TransListenerCoreTest_CopyFileFromSoftBus_001 + * @tc.desc: Test function of TransListenerCore::CopyFileFromSoftBus interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CopyFileFromSoftBus_001"; + + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + shared_ptr transListener(new TransListenerCore); + std::shared_ptr infos(new FsFileInfos); + transListener->copyEvent_.copyResult = FAILED; + + auto res = transListener->CopyFileFromSoftBus(srcUri, "destUri", infos, nullptr); + + EXPECT_EQ(res, EIO); + + GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CopyFileFromSoftBus_001"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file -- Gitee From 715db4cd048b1800666e49ac48c906c9736bdb02 Mon Sep 17 00:00:00 2001 From: tianp Date: Thu, 19 Jun 2025 16:59:29 +0800 Subject: [PATCH 7/9] =?UTF-8?q?HandleProgress=E6=96=B0=E5=A2=9E+copyTDD?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tianp Change-Id: I395ab668862455962477caa3511489f717604935 --- interfaces/test/unittest/BUILD.gn | 1 + interfaces/test/unittest/js/BUILD.gn | 8 + .../mod_fs/properties/copy_core_mock_test.cpp | 172 +++++++ .../js/mod_fs/properties/copy_core_test.cpp | 423 +++++++++++++++++- .../mod_fs/properties/mock/inotify_mock.cpp | 41 ++ .../js/mod_fs/properties/mock/inotify_mock.h | 51 +++ .../mod_fs/properties/trans_listener_test.cpp | 2 +- 7 files changed, 696 insertions(+), 2 deletions(-) create mode 100644 interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 5578deae0..527a36cb5 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -16,6 +16,7 @@ group("file_api_unittest") { deps = [ "class_file:class_file_test", "filemgmt_libn_test:filemgmt_libn_test", + "js:ani_file_environment_test", "js:ani_file_fs_mock_test", "js:ani_file_fs_test", "js:ani_file_hash_test", diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index e32056d7e..18de62878 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -96,7 +96,9 @@ ohos_unittest("ani_file_fs_mock_test") { "${file_api_path}/interfaces/kits/js/src/mod_fs/class_readeriterator", "${file_api_path}/interfaces/kits/js/src/mod_fs/class_stat", "${file_api_path}/interfaces/kits/js/src/mod_fs/class_stream", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_tasksignal", "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/copy_listener", "${file_api_path}/interfaces/test/unittest/js/mod_fs/class_stream/mock", "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock", ] @@ -107,9 +109,12 @@ ohos_unittest("ani_file_fs_mock_test") { "mod_fs/class_stat/fs_stat_mock_test.cpp", "mod_fs/class_stream/fs_stream_mock_test.cpp", "mod_fs/class_stream/mock/c_mock.cpp", + "mod_fs/properties/access_core_mock_test.cpp", + "mod_fs/properties/copy_core_mock_test.cpp", "mod_fs/properties/create_randomaccessfile_core_mock_test.cpp", "mod_fs/properties/dup_core_mock_test.cpp", "mod_fs/properties/lstat_core_mock_test.cpp", + "mod_fs/properties/mock/inotify_mock.cpp", "mod_fs/properties/mock/system_mock.cpp", "mod_fs/properties/mock/uv_fs_mock.cpp", "mod_fs/properties/open_core_mock_test.cpp", @@ -133,6 +138,8 @@ ohos_unittest("ani_file_fs_mock_test") { "ability_runtime:ability_manager", "app_file_service:fileuri_native", "c_utils:utils", + "dfs_service:distributed_file_daemon_kit_inner", + "dfs_service:libdistributedfileutils", "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", @@ -140,6 +147,7 @@ ohos_unittest("ani_file_fs_mock_test") { "libuv:uv", ] + defines = [ "private=public", ] diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp new file mode 100644 index 000000000..2ad56f7f5 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -0,0 +1,172 @@ +/* + * 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 + +#include "copy_core.h" +#include "inotify_mock.h" +#include "mock/uv_fs_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class CopyCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; + + static const string testDir; + static const string srcDir; + static const string destDir; + static const string srcFile; + static const string destFile; +}; + +const string CopyCoreMockTest::testDir = "/data/test"; +const string CopyCoreMockTest::srcDir = testDir + "/src"; +const string CopyCoreMockTest::destDir = testDir + "/dest"; +const string CopyCoreMockTest::srcFile = srcDir + "/src.txt"; +const string CopyCoreMockTest::destFile = destDir + "/dest.txt"; + +void CopyCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + mkdir(testDir.c_str(), 0755); + mkdir(srcDir.c_str(), 0755); + mkdir(destDir.c_str(), 0755); + int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } + uvMock = std::make_shared(); + Uvfs::ins = uvMock; +} + +void CopyCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + remove(srcFile.c_str()); + rmdir(srcDir.c_str()); + rmdir(destDir.c_str()); + rmdir(testDir.c_str()); + Uvfs::ins = nullptr; + uvMock = nullptr; +} + +void CopyCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void CopyCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; + remove(destFile.c_str()); +} + +/** + * @tc.name: CopyCoreMockTest_CopyFile_001 + * @tc.desc: Test function of CopyCore::CopyFile interface for file copy FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopyFile_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_CopyFile_001"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = CopyCoreMockTest::srcFile; + infos->destPath = CopyCoreMockTest::destFile; + + EXPECT_CALL(*uvMock, uv_fs_sendfile(_, _, _, _, _, _, _)).WillOnce(Return(-1)); + + auto res = CopyCore::CopyFile(srcFile, destFile, infos); + EXPECT_EQ(res, errno); + + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_CopyFile_001"; +} + +/** + * @tc.name: CopyCoreMockTest_DoCopy_001 + * @tc.desc: Test function of CopyCore::DoCopy interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_DoCopy_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_DoCopy_001"; + + string srcUri = "file://" + srcFile; + string destUri = "file://" + destFile; + optional options; + + EXPECT_CALL(*uvMock, uv_fs_sendfile(_, _, _, _, _, _, _)).WillOnce(Return(0)); + + auto res = CopyCore::DoCopy(srcUri, destUri, options); + EXPECT_EQ(res.IsSuccess(), true); + EXPECT_TRUE(filesystem::exists(destFile)); + + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_DoCopy_001"; +} + +/** + * @tc.name: CopyCoreMockTest_CopySubDir_001 + * @tc.desc: Test function of CopyCore::CopySubDir interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_CopySubDir_001"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), 0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } + + testing::StrictMock &inotifyMock = static_cast &>(GetInotifyMock()); + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + infos->notifyFd = 1; + EXPECT_CALL(inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(100)); + auto res = CopyCore::CopySubDir(subDir, destSubDir, infos); + testing::Mock::VerifyAndClearExpectations(&inotifyMock); + EXPECT_EQ(res, UNKNOWN_ERR); + + remove(subFile.c_str()); + rmdir(subDir.c_str()); + rmdir(destSubDir.c_str()); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_CopySubDir_001"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp index 088817b9c..34ed69f4c 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -216,6 +216,23 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_IsFile_002, testing::ext::TestSize.Level1) GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsFile_002"; } +/** + * @tc.name: CopyCoreTest_IsMediaUri_001 + * @tc.desc: Test function of CopyCore::IsMediaUri interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_IsMediaUri_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_IsMediaUri_001"; + + auto res = CopyCore::IsMediaUri(srcFile); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_IsMediaUri_001"; +} + /** * @tc.name: CopyCoreTest_GetFileSize_001 * @tc.desc: Test function of CopyCore::GetFileSize interface for success. @@ -455,6 +472,37 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_001, testing::ext::TestSize.Level GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CopySubDir_001"; } +/** + * @tc.name: CopyCoreTest_CopySubDir_002 + * @tc.desc: Test function of CopyCore::CopySubDir interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopySubDir_002"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), 0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + if (fd >= 0) { + close(fd); + } + + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + infos->notifyFd = 1; + auto res = CopyCore::CopySubDir(subDir, destSubDir, infos); + EXPECT_EQ(res, errno); + + remove(subFile.c_str()); + rmdir(subDir.c_str()); + rmdir(destSubDir.c_str()); + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CopySubDir_002"; +} + /** * @tc.name: CopyCoreTest_RecurCopyDir_001 * @tc.desc: Test function of CopyCore::RecurCopyDir interface for success. @@ -540,8 +588,8 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ExecLocal_001, testing::ext::TestSize.Level1 infos->isFile = true; infos->srcPath = srcFile; infos->destPath = destFile; - auto callback = make_shared(nullptr); + auto res = CopyCore::ExecLocal(infos, callback); EXPECT_EQ(res, ERRNO_NOERR); EXPECT_TRUE(CopyCore::IsFile(destFile)); @@ -549,6 +597,29 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ExecLocal_001, testing::ext::TestSize.Level1 GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ExecLocal_001"; } +/** + * @tc.name: CopyCoreTest_ExecLocal_002 + * @tc.desc: Test function of CopyCore::ExecLocal interface for file copy FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_ExecLocal_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ExecLocal_002"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = srcFile; + infos->destPath = srcFile; + auto callback = make_shared(nullptr); + + auto res = CopyCore::ExecLocal(infos, callback); + EXPECT_EQ(res, EINVAL); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ExecLocal_002"; +} + /** * @tc.name: CopyCoreTest_RegisterListener_001 * @tc.desc: Test function of CopyCore::RegisterListener interface for success. @@ -623,4 +694,354 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_DoCopy_001, testing::ext::TestSize.Level1) GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_DoCopy_001"; } +/** + * @tc.name: CopyCoreTest_DoCopy_002 + * @tc.desc: Test function of CopyCore::DoCopy interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_DoCopy_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_DoCopy_002"; + + string src = "file:///data/test/src/src.txt"; + string dest = "file:///data/test/dest/dest.txt"; + optional options; + + auto res = CopyCore::DoCopy(src, dest, options); + EXPECT_TRUE(res.IsSuccess()); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_DoCopy_002"; +} + +/** + * @tc.name: CopyCoreTest_GetDirSize_001 + * @tc.desc: Test function of CopyCore::GetDirSize interface for file copy success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetDirSize_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetDirSize_001"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = srcFile; + infos->destPath = destFile; + + auto res = CopyCore::GetDirSize(infos, srcDir); + EXPECT_EQ(res, 0); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetDirSize_001"; +} + +/** + * @tc.name: CopyCoreTest_GetUVEntry_001 + * @tc.desc: Test function of CopyCore::GetUVEntry interface for file copy FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetUVEntry_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetUVEntry_001"; + + auto infos = make_shared(); + auto res = CopyCore::GetUVEntry(infos); + EXPECT_EQ(res, nullptr); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetUVEntry_001"; +} + +/** + * @tc.name: CopyCoreTest_CheckFileValid_001 + * @tc.desc: Test function of CopyCore::CheckFileValid interface for file copy FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CheckFileValid_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CheckFileValid_001"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = srcFile; + infos->destPath = destFile; + + auto res = CopyCore::CheckFileValid(srcFile, infos); + EXPECT_EQ(res, false); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CheckFileValid_001"; +} + +/** + * @tc.name: CopyCoreTest_UpdateProgressSize_001 + * @tc.desc: Test function of CopyCore::UpdateProgressSize interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_UpdateProgressSize_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_UpdateProgressSize_001"; + + auto receivedInfo = make_shared(); + auto callback = make_shared(nullptr); + + auto res = CopyCore::UpdateProgressSize(srcFile, receivedInfo, callback); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_UpdateProgressSize_001"; +} + +/** + * @tc.name: CopyCoreTest_GetRegisteredListener_001 + * @tc.desc: Test function of CopyCore::GetRegisteredListener interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetRegisteredListener_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetRegisteredListener_001"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = srcFile; + infos->destPath = destFile; + + auto res = CopyCore::GetRegisteredListener(infos); + EXPECT_EQ(res, nullptr); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetRegisteredListener_001"; +} + +/** + * @tc.name: CopyCoreTest_SubscribeLocalListener_001 + * @tc.desc: Test function of CopyCore::SubscribeLocalListener interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_SubscribeLocalListener_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_SubscribeLocalListener_001"; + + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = srcFile; + infos->destPath = destFile; + auto callback = make_shared(nullptr); + + auto res = CopyCore::SubscribeLocalListener(infos, callback); + EXPECT_EQ(res, errno); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_SubscribeLocalListener_001"; +} + +/** + * @tc.name: CopyCoreTest_GetRealPath_001 + * @tc.desc: Test function of CopyCore::GetRealPath interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetRealPath_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetRealPath_001"; + + string path = "./data/test/src/src.txt"; + + auto res = CopyCore::GetRealPath(path); + EXPECT_EQ(res, "data/test/src/src.txt"); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetRealPath_001"; +} + +/** + * @tc.name: CopyCoreTest_GetRealPath_002 + * @tc.desc: Test function of CopyCore::GetRealPath interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_GetRealPath_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_GetRealPath_002"; + + string path = "../data/test/src/src.txt"; + + auto res = CopyCore::GetRealPath(path); + EXPECT_EQ(res, "data/test/src/src.txt"); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_GetRealPath_002"; +} + +/** + * @tc.name: CopyCoreTest_ExecCopy_001 + * @tc.desc: Test function of CopyCore::ExecCopy interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_ExecCopy_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_ExecCopy_001"; + + auto infos = make_shared(); + infos->isFile = false; + infos->srcPath = "/data/test/src"; + infos->destPath = "/data/test/dest"; + + auto res = CopyCore::ExecCopy(infos); + EXPECT_EQ(res, ERRNO_NOERR); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ExecCopy_001"; +} + +/** + * @tc.name: CopyCoreTest_CopyFile_001 + * @tc.desc: Test function of CopyCore::CopyFile interface for file copy FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_CopyFile_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopyFile_001"; + + string src = "datashare:///media/src_test.jpg"; + string dest = "datashare:///media/dest_test.jpg"; + auto infos = make_shared(); + infos->isFile = true; + infos->srcPath = src; + infos->destPath = dest; + + auto res = CopyCore::CopyFile(src, dest, infos); + EXPECT_EQ(res, errno); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CopyFile_001"; +} + +/** + * @tc.name: CopyCoreTest_HandleProgress_001 + * @tc.desc: Test function of CopyCore::HandleProgress interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_HandleProgress_001"; + + auto infos = make_shared(); + infos->isFile = false; + infos->srcPath = "/data/test/src"; + infos->destPath = "/data/test/dest"; + + auto event = make_unique(); + const int testWd = 123; + event->wd = testWd; + event->mask = IN_MODIFY; + event->len = 0; + // 执行处理 + auto [continueProcess, errCode, needSend] = CopyCore::HandleProgress(event.get(), infos, nullptr); + + // 验证结果 + EXPECT_TRUE(continueProcess); + EXPECT_EQ(errCode, EINVAL); + EXPECT_FALSE(needSend); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_HandleProgress_001"; +} + +/** + * @tc.name: CopyCoreTest_HandleProgress_002 + * @tc.desc: Test function of CopyCore::HandleProgress interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_HandleProgress_002"; + + auto infos = make_shared(); + infos->srcPath = srcDir; + infos->destPath = destDir; + infos->isFile = true; + + auto callback = make_shared(nullptr); + + // 添加接收信息(使用不同的wd) + const int testWd = 123; + const int differentWd = 456; + auto receiveInfo = make_shared(); + receiveInfo->path = testDir; + callback->wds.push_back({differentWd, receiveInfo}); + + // 初始化事件结构 + auto event = make_unique(); + event->wd = testWd; + event->mask = IN_MODIFY; + event->len = 0; + + // 执行处理 + auto [continueProcess, errCode, needSend] = + CopyCore::HandleProgress(event.get(), infos, callback); + + // 验证结果 + EXPECT_TRUE(continueProcess); + EXPECT_EQ(errCode, EINVAL); + EXPECT_FALSE(needSend); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_HandleProgress_002"; +} + +/** + * @tc.name: CopyCoreTest_HandleProgress_003 + * @tc.desc: Test function of CopyCore::HandleProgress interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_HandleProgress_003"; + + // 创建测试用的文件信息对象 + auto infos = make_shared(); + infos->srcPath = srcDir; + infos->destPath = destDir; + infos->isFile = true; + + // 创建测试用的回调对象 + auto callback = make_shared(nullptr); + + // 添加匹配的接收信息 + const int testWd = 123; + auto receiveInfo = make_shared(); + receiveInfo->path = srcFile; + callback->wds.push_back({testWd, receiveInfo}); + + // 初始化事件结构 + auto event = make_unique(); + event->wd = testWd; + event->mask = IN_MODIFY; + event->len = 0; + + // 执行处理 + auto [continueProcess, errCode, needSend] = CopyCore::HandleProgress(event.get(), infos, callback); + + // 验证结果 + EXPECT_TRUE(continueProcess); + EXPECT_EQ(errCode, ERRNO_NOERR); + EXPECT_TRUE(needSend); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_HandleProgress_003"; +} + } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp new file mode 100644 index 000000000..67c5c1a26 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp @@ -0,0 +1,41 @@ +/* + * 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 "inotify_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +InotifyMock &GetInotifyMock() +{ + return InotifyMock::GetMock(); +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int inotify_add_watch(int fd, const char *pathname, uint32_t mask) +{ + return GetInotifyMock().inotify_add_watch(fd, pathname, mask); +} + +} // extern "C" \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h new file mode 100644 index 000000000..803b20944 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h @@ -0,0 +1,51 @@ +/* + * 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 INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H + +#include +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class IInotifyMock { +public: + virtual ~IInotifyMock() = default; + virtual int inotify_add_watch(int, const char *, uint32_t) = 0; +}; + +class InotifyMock : public IInotifyMock { +public: + MOCK_METHOD(int, inotify_add_watch, (int, const char *, uint32_t), (override)); + + static InotifyMock &GetMock() + { + static InotifyMock mock; + return mock; + } +}; + +InotifyMock &GetInotifyMock(); + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp index b1a727d4e..9570deda6 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp @@ -115,7 +115,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CreateDfsCopyPath_001, tes GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CreateDfsCopyPath_001"; string result = TransListenerCore::CreateDfsCopyPath(); - EXPECT_EQ(result, "/data/storage/el2/distributedfiles/"); + EXPECT_FALSE(result.empty()); GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CreateDfsCopyPath_001"; } -- Gitee From 29ac694687cd8a4280739774055e721249eaf7ca Mon Sep 17 00:00:00 2001 From: tianp Date: Wed, 25 Jun 2025 19:50:07 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E6=84=8F=E8=A7=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tianp Change-Id: I3c1858a4b6611ed9a381e99ba2ed90f9b5a02088 --- .../ani/task_signal_listener_ani.h | 2 +- .../ani/task_signal_wrapper.h | 2 +- .../copy_listener/trans_listener_core.h | 2 +- interfaces/test/unittest/js/BUILD.gn | 7 +- .../class_tasksignal/fs_task_signal_test.cpp | 13 +- .../mod_fs/properties/copy_core_mock_test.cpp | 19 ++- .../js/mod_fs/properties/copy_core_test.cpp | 140 +++++++++--------- .../mod_fs/properties/mock/inotify_mock.cpp | 2 +- .../js/mod_fs/properties/mock/inotify_mock.h | 2 +- .../properties/trans_listener_mock_test.cpp | 53 +++---- .../mod_fs/properties/trans_listener_test.cpp | 57 ++----- 11 files changed, 132 insertions(+), 167 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h index a11be571b..ae02a941e 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_listener_ani.h @@ -44,4 +44,4 @@ private: } // namespace OHOS::FileManagement::ModuleFileIO::ANI -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_LISTENER_ANI_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_LISTENER_ANI_H diff --git a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h index 2cfd04e4d..4fe9fb143 100644 --- a/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h +++ b/interfaces/kits/js/src/mod_fs/class_tasksignal/ani/task_signal_wrapper.h @@ -34,4 +34,4 @@ public: } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_WRAPPER_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_TASKSIGNAL_ANI_TASK_SIGNAL_WRAPPER_H diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h index c797454de..9688e7940 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h @@ -67,4 +67,4 @@ private: } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index 18de62878..b3350ec9d 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -49,6 +49,7 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/properties/lstat_core_test.cpp", "mod_fs/properties/open_core_test.cpp", "mod_fs/properties/read_core_test.cpp", + "mod_fs/properties/read_lines_core_test.cpp", "mod_fs/properties/read_text_core_test.cpp", "mod_fs/properties/rmdir_core_test.cpp", "mod_fs/properties/trans_listener_test.cpp", @@ -113,16 +114,20 @@ ohos_unittest("ani_file_fs_mock_test") { "mod_fs/properties/copy_core_mock_test.cpp", "mod_fs/properties/create_randomaccessfile_core_mock_test.cpp", "mod_fs/properties/dup_core_mock_test.cpp", + "mod_fs/properties/fdatasync_core_mock_test.cpp", "mod_fs/properties/lstat_core_mock_test.cpp", "mod_fs/properties/mock/inotify_mock.cpp", "mod_fs/properties/mock/system_mock.cpp", "mod_fs/properties/mock/uv_fs_mock.cpp", "mod_fs/properties/open_core_mock_test.cpp", "mod_fs/properties/read_core_mock_test.cpp", + "mod_fs/properties/read_lines_core_mock_test.cpp", "mod_fs/properties/symlink_core_mock_test.cpp", "mod_fs/properties/trans_listener_mock_test.cpp", "mod_fs/properties/truncate_core_mock_test.cpp", + "mod_fs/properties/unlink_core_mock_test.cpp", "mod_fs/properties/utimes_core_mock_test.cpp", + "mod_fs/properties/xattr_core_mock_test.cpp", ] deps = [ @@ -147,8 +152,8 @@ ohos_unittest("ani_file_fs_mock_test") { "libuv:uv", ] - defines = [ + "ENABLE_DISTRIBUTED_FILE_MOCK", "private=public", ] } diff --git a/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp b/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp index 7a429951b..923204771 100644 --- a/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_tasksignal/fs_task_signal_test.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ - #include "fs_task_signal.h" #include @@ -102,7 +101,7 @@ HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Constructor_002, testing::ext::TestS /** * @tc.name: FsTaskSignalTest_Constructor_003 - * @tc.desc: Test function of FsTaskSignal::Constructor interface for SUCCESS. + * @tc.desc: Test function of FsTaskSignal::Constructor interface for True. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -124,7 +123,7 @@ HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Constructor_003, testing::ext::TestS /** * @tc.name: FsTaskSignalTest_Cancel_001 - * @tc.desc: Test function of FsTaskSignal::Cancel interface for false. + * @tc.desc: Test function of FsTaskSignal::Cancel interface for False. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -143,7 +142,7 @@ HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Cancel_001, testing::ext::TestSize.L /** * @tc.name: FsTaskSignalTest_Cancel_002 - * @tc.desc: Test function of FsTaskSignal::Cancel interface for false. + * @tc.desc: Test function of FsTaskSignal::Cancel interface for False. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -163,7 +162,7 @@ HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_Cancel_002, testing::ext::TestSize.L /** * @tc.name: FsTaskSignalTest_OnCancel_001 - * @tc.desc: Test function of FsTaskSignal::OnCancel interface for false. + * @tc.desc: Test function of FsTaskSignal::OnCancel interface for False. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -182,7 +181,7 @@ HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_OnCancel_001, testing::ext::TestSize /** * @tc.name: FsTaskSignalTest_OnCancel_002 - * @tc.desc: Test function of FsTaskSignal::OnCancel interface for false. + * @tc.desc: Test function of FsTaskSignal::OnCancel interface for False. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -200,4 +199,4 @@ HWTEST_F(FsTaskSignalTest, FsTaskSignalTest_OnCancel_002, testing::ext::TestSize GTEST_LOG_(INFO) << "NClassTest-end FsTaskSignalTest_OnCancel_002"; } -} // OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file +} // OHOS::FileManagement::ModuleFileIO::Test diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp index 2ad56f7f5..9f914b2af 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -56,9 +56,10 @@ void CopyCoreMockTest::SetUpTestCase(void) mkdir(srcDir.c_str(), 0755); mkdir(destDir.c_str(), 0755); int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); uvMock = std::make_shared(); Uvfs::ins = uvMock; } @@ -66,7 +67,8 @@ void CopyCoreMockTest::SetUpTestCase(void) void CopyCoreMockTest::TearDownTestCase(void) { GTEST_LOG_(INFO) << "TearDownTestCase"; - remove(srcFile.c_str()); + int ret = remove(srcFile.c_str()); + EXPECT_TRUE(ret == 0); rmdir(srcDir.c_str()); rmdir(destDir.c_str()); rmdir(testDir.c_str()); @@ -87,7 +89,7 @@ void CopyCoreMockTest::TearDown(void) /** * @tc.name: CopyCoreMockTest_CopyFile_001 - * @tc.desc: Test function of CopyCore::CopyFile interface for file copy FALSE. + * @tc.desc: Test function of CopyCore::CopyFile interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -148,9 +150,10 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_001, testing::ext::TestSi mkdir(subDir.c_str(), 0755); string subFile = subDir + "/sub_file.txt"; int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); testing::StrictMock &inotifyMock = static_cast &>(GetInotifyMock()); string destSubDir = destDir + "/sub_dir"; @@ -158,7 +161,7 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_001, testing::ext::TestSi infos->notifyFd = 1; EXPECT_CALL(inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) .Times(1) - .WillOnce(testing::Return(100)); + .WillOnce(testing::Return(0)); auto res = CopyCore::CopySubDir(subDir, destSubDir, infos); testing::Mock::VerifyAndClearExpectations(&inotifyMock); EXPECT_EQ(res, UNKNOWN_ERR); @@ -169,4 +172,4 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_001, testing::ext::TestSi GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_CopySubDir_001"; } -} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO::Test diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp index 34ed69f4c..ed452c1d0 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -24,6 +24,8 @@ using namespace testing; using namespace testing::ext; using namespace std; +const int g_permissions = 0755; + class CopyCoreTest : public testing::Test { public: static void SetUpTestCase(void); @@ -47,19 +49,21 @@ const string CopyCoreTest::destFile = destDir + "/dest.txt"; void CopyCoreTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; - mkdir(testDir.c_str(), 0755); - mkdir(srcDir.c_str(), 0755); - mkdir(destDir.c_str(), 0755); + mkdir(testDir.c_str(), g_permissions); + mkdir(srcDir.c_str(), g_permissions); + mkdir(destDir.c_str(), g_permissions); int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); } void CopyCoreTest::TearDownTestCase(void) { GTEST_LOG_(INFO) << "TearDownTestCase"; - remove(srcFile.c_str()); + int ret = remove(srcFile.c_str()); + EXPECT_TRUE(ret == 0); rmdir(srcDir.c_str()); rmdir(destDir.c_str()); rmdir(testDir.c_str()); @@ -73,7 +77,6 @@ void CopyCoreTest::SetUp(void) void CopyCoreTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; - remove(destFile.c_str()); } /** @@ -235,7 +238,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_IsMediaUri_001, testing::ext::TestSize.Level /** * @tc.name: CopyCoreTest_GetFileSize_001 - * @tc.desc: Test function of CopyCore::GetFileSize interface for success. + * @tc.desc: Test function of CopyCore::GetFileSize interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -253,7 +256,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_GetFileSize_001, testing::ext::TestSize.Leve /** * @tc.name: CopyCoreTest_GetFileSize_002 - * @tc.desc: Test function of CopyCore::GetFileSize interface for failure. + * @tc.desc: Test function of CopyCore::GetFileSize interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -272,7 +275,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_GetFileSize_002, testing::ext::TestSize.Leve /** * @tc.name: CopyCoreTest_CheckOrCreatePath_001 - * @tc.desc: Test function of CopyCore::CheckOrCreatePath interface for existing file. + * @tc.desc: Test function of CopyCore::CheckOrCreatePath interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -289,7 +292,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CheckOrCreatePath_001, testing::ext::TestSiz /** * @tc.name: CopyCoreTest_CheckOrCreatePath_002 - * @tc.desc: Test function of CopyCore::CheckOrCreatePath interface for creating new file. + * @tc.desc: Test function of CopyCore::CheckOrCreatePath interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -308,7 +311,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CheckOrCreatePath_002, testing::ext::TestSiz /** * @tc.name: CopyCoreTest_MakeDir_001 - * @tc.desc: Test function of CopyCore::MakeDir interface for success. + * @tc.desc: Test function of CopyCore::MakeDir interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -328,10 +331,10 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_001, testing::ext::TestSize.Level1) /** * @tc.name: CopyCoreTest_MakeDir_002 - * @tc.desc: Test function of CopyCore::MakeDir interface for existing directory. + * @tc.desc: Test function of CopyCore::MakeDir interface for TRUE. * @tc.size: SMALL * @tc.type: FUNC - * @tc.level Level 2 + * @tc.level Level 1 */ HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_002, testing::ext::TestSize.Level1) { @@ -345,10 +348,10 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_002, testing::ext::TestSize.Level1) /** * @tc.name: CopyCoreTest_MakeDir_003 - * @tc.desc: Test function of CopyCore::MakeDir interface for invalid path. + * @tc.desc: Test function of CopyCore::MakeDir interface for FALSE. * @tc.size: SMALL * @tc.type: FUNC - * @tc.level Level 2 + * @tc.level Level 1 */ HWTEST_F(CopyCoreTest, CopyCoreTest_MakeDir_003, testing::ext::TestSize.Level1) { @@ -440,7 +443,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CreateFileInfos_001, testing::ext::TestSize. /** * @tc.name: CopyCoreTest_CopySubDir_001 - * @tc.desc: Test function of CopyCore::CopySubDir interface for success. + * @tc.desc: Test function of CopyCore::CopySubDir interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -450,12 +453,13 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_001, testing::ext::TestSize.Level GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopySubDir_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), 0755); + mkdir(subDir.c_str(), g_permissions); string subFile = subDir + "/sub_file.txt"; int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); string destSubDir = destDir + "/sub_dir"; auto infos = make_shared(); @@ -474,7 +478,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_001, testing::ext::TestSize.Level /** * @tc.name: CopyCoreTest_CopySubDir_002 - * @tc.desc: Test function of CopyCore::CopySubDir interface for success. + * @tc.desc: Test function of CopyCore::CopySubDir interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -484,12 +488,13 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_002, testing::ext::TestSize.Level GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopySubDir_002"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), 0755); + mkdir(subDir.c_str(), g_permissions); string subFile = subDir + "/sub_file.txt"; int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); string destSubDir = destDir + "/sub_dir"; auto infos = make_shared(); @@ -505,7 +510,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_002, testing::ext::TestSize.Level /** * @tc.name: CopyCoreTest_RecurCopyDir_001 - * @tc.desc: Test function of CopyCore::RecurCopyDir interface for success. + * @tc.desc: Test function of CopyCore::RecurCopyDir interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -515,12 +520,13 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_RecurCopyDir_001, testing::ext::TestSize.Lev GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_RecurCopyDir_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), 0755); + mkdir(subDir.c_str(), g_permissions); string subFile = subDir + "/sub_file.txt"; int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); string destSubDir = destDir + "/sub_dir"; auto infos = make_shared(); @@ -539,7 +545,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_RecurCopyDir_001, testing::ext::TestSize.Lev /** * @tc.name: CopyCoreTest_CopyDirFunc_001 - * @tc.desc: Test function of CopyCore::CopyDirFunc interface for success. + * @tc.desc: Test function of CopyCore::CopyDirFunc interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -549,12 +555,13 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopyDirFunc_001, testing::ext::TestSize.Leve GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopyDirFunc_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), 0755); + mkdir(subDir.c_str(), g_permissions); string subFile = subDir + "/sub_file.txt"; int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); - if (fd >= 0) { - close(fd); + if (fd < 0) { + EXPECT_TRUE(false); } + close(fd); string destSubDir = destDir + "/src/sub_dir"; string destSubFile = destSubDir + "/sub_file.txt"; @@ -575,7 +582,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopyDirFunc_001, testing::ext::TestSize.Leve /** * @tc.name: CopyCoreTest_ExecLocal_001 - * @tc.desc: Test function of CopyCore::ExecLocal interface for file copy success. + * @tc.desc: Test function of CopyCore::ExecLocal interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -593,13 +600,15 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ExecLocal_001, testing::ext::TestSize.Level1 auto res = CopyCore::ExecLocal(infos, callback); EXPECT_EQ(res, ERRNO_NOERR); EXPECT_TRUE(CopyCore::IsFile(destFile)); + int ret = remove(destFile.c_str()); + EXPECT_TRUE(ret == 0); GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_ExecLocal_001"; } /** * @tc.name: CopyCoreTest_ExecLocal_002 - * @tc.desc: Test function of CopyCore::ExecLocal interface for file copy FALSE. + * @tc.desc: Test function of CopyCore::ExecLocal interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -622,7 +631,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_ExecLocal_002, testing::ext::TestSize.Level1 /** * @tc.name: CopyCoreTest_RegisterListener_001 - * @tc.desc: Test function of CopyCore::RegisterListener interface for success. + * @tc.desc: Test function of CopyCore::RegisterListener interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -647,7 +656,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_RegisterListener_001, testing::ext::TestSize /** * @tc.name: CopyCoreTest_UnregisterListener_001 - * @tc.desc: Test function of CopyCore::UnregisterListener interface for success. + * @tc.desc: Test function of CopyCore::UnregisterListener interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -673,7 +682,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_UnregisterListener_001, testing::ext::TestSi /** * @tc.name: CopyCoreTest_DoCopy_001 - * @tc.desc: Test function of CopyCore::DoCopy interface for failure (invalid params). + * @tc.desc: Test function of CopyCore::DoCopy interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -696,7 +705,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_DoCopy_001, testing::ext::TestSize.Level1) /** * @tc.name: CopyCoreTest_DoCopy_002 - * @tc.desc: Test function of CopyCore::DoCopy interface for success. + * @tc.desc: Test function of CopyCore::DoCopy interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -711,13 +720,15 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_DoCopy_002, testing::ext::TestSize.Level1) auto res = CopyCore::DoCopy(src, dest, options); EXPECT_TRUE(res.IsSuccess()); + int ret = remove(destFile.c_str()); + EXPECT_TRUE(ret == 0); GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_DoCopy_002"; } /** * @tc.name: CopyCoreTest_GetDirSize_001 - * @tc.desc: Test function of CopyCore::GetDirSize interface for file copy success. + * @tc.desc: Test function of CopyCore::GetDirSize interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -739,7 +750,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_GetDirSize_001, testing::ext::TestSize.Level /** * @tc.name: CopyCoreTest_GetUVEntry_001 - * @tc.desc: Test function of CopyCore::GetUVEntry interface for file copy FALSE. + * @tc.desc: Test function of CopyCore::GetUVEntry interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -757,7 +768,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_GetUVEntry_001, testing::ext::TestSize.Level /** * @tc.name: CopyCoreTest_CheckFileValid_001 - * @tc.desc: Test function of CopyCore::CheckFileValid interface for file copy FALSE. + * @tc.desc: Test function of CopyCore::CheckFileValid interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -779,7 +790,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CheckFileValid_001, testing::ext::TestSize.L /** * @tc.name: CopyCoreTest_UpdateProgressSize_001 - * @tc.desc: Test function of CopyCore::UpdateProgressSize interface for success. + * @tc.desc: Test function of CopyCore::UpdateProgressSize interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -844,7 +855,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_SubscribeLocalListener_001, testing::ext::Te /** * @tc.name: CopyCoreTest_GetRealPath_001 - * @tc.desc: Test function of CopyCore::GetRealPath interface for SUCCESS. + * @tc.desc: Test function of CopyCore::GetRealPath interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -863,7 +874,7 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_GetRealPath_001, testing::ext::TestSize.Leve /** * @tc.name: CopyCoreTest_GetRealPath_002 - * @tc.desc: Test function of CopyCore::GetRealPath interface for SUCCESS. + * @tc.desc: Test function of CopyCore::GetRealPath interface for TRUE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -943,14 +954,12 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_001, testing::ext::TestSize.L infos->destPath = "/data/test/dest"; auto event = make_unique(); - const int testWd = 123; + const int testWd = 123; //模拟wd数值为123 event->wd = testWd; event->mask = IN_MODIFY; event->len = 0; - // 执行处理 auto [continueProcess, errCode, needSend] = CopyCore::HandleProgress(event.get(), infos, nullptr); - - // 验证结果 + EXPECT_TRUE(continueProcess); EXPECT_EQ(errCode, EINVAL); EXPECT_FALSE(needSend); @@ -976,24 +985,19 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_002, testing::ext::TestSize.L auto callback = make_shared(nullptr); - // 添加接收信息(使用不同的wd) - const int testWd = 123; - const int differentWd = 456; + const int testWd = 123; //模拟wd数值为123 + const int differentWd = 456; //模拟wd数值为456 auto receiveInfo = make_shared(); receiveInfo->path = testDir; callback->wds.push_back({differentWd, receiveInfo}); - // 初始化事件结构 auto event = make_unique(); event->wd = testWd; event->mask = IN_MODIFY; event->len = 0; - - // 执行处理 - auto [continueProcess, errCode, needSend] = - CopyCore::HandleProgress(event.get(), infos, callback); - - // 验证结果 + + auto [continueProcess, errCode, needSend] = CopyCore::HandleProgress(event.get(), infos, callback); + EXPECT_TRUE(continueProcess); EXPECT_EQ(errCode, EINVAL); EXPECT_FALSE(needSend); @@ -1011,32 +1015,26 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_002, testing::ext::TestSize.L HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_003, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_HandleProgress_003"; - - // 创建测试用的文件信息对象 + auto infos = make_shared(); infos->srcPath = srcDir; infos->destPath = destDir; infos->isFile = true; - - // 创建测试用的回调对象 + auto callback = make_shared(nullptr); - - // 添加匹配的接收信息 + const int testWd = 123; auto receiveInfo = make_shared(); receiveInfo->path = srcFile; callback->wds.push_back({testWd, receiveInfo}); - - // 初始化事件结构 + auto event = make_unique(); event->wd = testWd; event->mask = IN_MODIFY; event->len = 0; - - // 执行处理 + auto [continueProcess, errCode, needSend] = CopyCore::HandleProgress(event.get(), infos, callback); - - // 验证结果 + EXPECT_TRUE(continueProcess); EXPECT_EQ(errCode, ERRNO_NOERR); EXPECT_TRUE(needSend); @@ -1044,4 +1042,4 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_HandleProgress_003, testing::ext::TestSize.L GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_HandleProgress_003"; } -} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO::Test diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp index 67c5c1a26..26696c869 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp @@ -38,4 +38,4 @@ int inotify_add_watch(int fd, const char *pathname, uint32_t mask) return GetInotifyMock().inotify_add_watch(fd, pathname, mask); } -} // extern "C" \ No newline at end of file +} // extern "C" diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h index 803b20944..3605671c1 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h @@ -48,4 +48,4 @@ InotifyMock &GetInotifyMock(); } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H \ No newline at end of file +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp index 56c11d8b5..287d5196f 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp @@ -48,17 +48,11 @@ public: return 0; } - // int32_t PrepareSession(const std::string &srcUri, const std::string &dstUri, const std::string &srcDeviceId, - // const sptr &listener, HmdfsInfo &info) override - // { - // return 0; - // } - MOCK_METHOD(int32_t, PrepareSession, (const std::string &srcUri, const std::string &dstUri, - const std::string &srcDeviceId, - const sptr &listener, HmdfsInfo &info), (override)); - - int32_t PushAsset( - int32_t userId, const sptr &assetObj, const sptr &sendCallback) override + MOCK_METHOD(int32_t, PrepareSession, (const std::string &srcUri, const std::string &dstUri, + const std::string &srcDeviceId, const sptr &listener, HmdfsInfo &info), (override)); + + int32_t PushAsset(int32_t userId, const sptr &assetObj, + const sptr &sendCallback) override { return 0; } @@ -125,7 +119,7 @@ using namespace testing; using namespace testing::ext; using namespace std; -string g_path = "/data/test/TransListenerCoreTest.txt"; +string g_path = "/data/test/TransListenerCoreMockTest.txt"; const string FILE_MANAGER_AUTHORITY = "docs"; const string MEDIA_AUTHORITY = "media"; @@ -134,7 +128,7 @@ public: void InvokeListener(uint64_t progressSize, uint64_t totalSize) const override {} }; -class TransListenerCoreTest : public testing::Test { +class TransListenerCoreMockTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); @@ -146,39 +140,42 @@ public: } }; -void TransListenerCoreTest::SetUpTestCase(void) +void TransListenerCoreMockTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; int32_t fd = open(g_path.c_str(), O_CREAT | O_RDWR, 0644); + if (fd < 0) { + EXPECT_TRUE(false); + } close(fd); } -void TransListenerCoreTest::TearDownTestCase(void) +void TransListenerCoreMockTest::TearDownTestCase(void) { rmdir(g_path.c_str()); GTEST_LOG_(INFO) << "TearDownTestCase"; } -void TransListenerCoreTest::SetUp(void) +void TransListenerCoreMockTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; } -void TransListenerCoreTest::TearDown(void) +void TransListenerCoreMockTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; } /** - * @tc.name: TransListenerCoreTest_PrepareCopySession_001 + * @tc.name: TransListenerCoreMockTest_PrepareCopySession_001 * @tc.desc: Test function of TransListenerCore::PrepareCopySession interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_001, testing::ext::TestSize.Level1) +HWTEST_F(TransListenerCoreMockTest, TransListenerCoreMockTest_PrepareCopySession_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_PrepareCopySession_001"; + GTEST_LOG_(INFO) << "TransListenerCoreMockTest-begin TransListenerCoreMockTest_PrepareCopySession_001"; Storage::DistributedFile::HmdfsInfo info; info.authority = FILE_MANAGER_AUTHORITY; @@ -192,19 +189,19 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_PrepareCopySession_001, te auto result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); EXPECT_EQ(result, ERRNO_NOERR); - GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_PrepareCopySession_001"; + GTEST_LOG_(INFO) << "TransListenerCoreMockTest-end TransListenerCoreMockTest_PrepareCopySession_001"; } /** - * @tc.name: TransListenerCoreTest_CopyFileFromSoftBus_001 + * @tc.name: TransListenerCoreMockTest_CopyFileFromSoftBus_001 * @tc.desc: Test function of TransListenerCore::CopyFileFromSoftBus interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, testing::ext::TestSize.Level1) +HWTEST_F(TransListenerCoreMockTest, TransListenerCoreMockTest_CopyFileFromSoftBus_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CopyFileFromSoftBus_001"; + GTEST_LOG_(INFO) << "TransListenerCoreMockTest-begin TransListenerCoreMockTest_CopyFileFromSoftBus_001"; Storage::DistributedFile::HmdfsInfo info; info.authority = FILE_MANAGER_AUTHORITY; @@ -212,10 +209,6 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, t string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; shared_ptr transListener(new TransListenerCore); std::shared_ptr infos(new FsFileInfos); - // transListener->copyEvent_.copyResult = FAILED; - - // shared_ptr transListenerArg(new TransListenerCore); - // transListenerArg->copyEvent_.errorCode = DFS_CANCEL_SUCCESS; EXPECT_CALL(GetMock(), PrepareSession(testing::_, testing::_, testing::_, testing::_, testing::_)) .WillOnce(testing::Return(ERRNO_NOERR)); @@ -223,7 +216,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, t auto res = transListener->CopyFileFromSoftBus(srcUri, "destUri", infos, nullptr); EXPECT_EQ(res, EIO); - GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CopyFileFromSoftBus_001"; + GTEST_LOG_(INFO) << "TransListenerCoreMockTest-end TransListenerCoreMockTest_CopyFileFromSoftBus_001"; } -} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO::Test diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp index 9570deda6..ff568f5fd 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp @@ -46,6 +46,9 @@ void TransListenerCoreTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; int32_t fd = open(g_path.c_str(), O_CREAT | O_RDWR, 0644); + if (fd < 0) { + EXPECT_TRUE(false); + } close(fd); } @@ -65,44 +68,6 @@ void TransListenerCoreTest::TearDown(void) GTEST_LOG_(INFO) << "TearDown"; } -// /** -// * @tc.name: TransListenerCoreTest_RmDir_001 -// * @tc.desc: Test function of TransListenerCore::RmDir interface for FALSE. -// * @tc.size: MEDIUM -// * @tc.type: FUNC -// * @tc.level Level 1 -// */ -// HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_RmDir_001, testing::ext::TestSize.Level1) -// { -// GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_RmDir_001"; - -// string path = "/data/test/TransListenerCoreTest_RmDir_001.txt"; - -// TransListenerCore::RmDir(path); - -// GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_RmDir_001"; -// } - -// /** -// * @tc.name: TransListenerCoreTest_RmDir_002 -// * @tc.desc: Test function of TransListenerCore::RmDir interface for SUCC. -// * @tc.size: MEDIUM -// * @tc.type: FUNC -// * @tc.level Level 1 -// */ -// HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_RmDir_002, testing::ext::TestSize.Level1) -// { -// GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_RmDir_002"; - -// string path = "/data/test/TransListenerCoreTest_RmDir_002.txt"; -// int32_t fd = open(path, O_CREAT | O_RDWR, 0644); -// close(fd); - -// TransListenerCore::RmDir(path); - -// GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_RmDir_002"; -// } - /** * @tc.name: TransListenerCoreTest_CreateDfsCopyPath_001 * @tc.desc: Test function of TransListenerCore::CreateDfsCopyPath interface for FALSE. @@ -155,6 +120,9 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_HandleCopyFailure_002, tes string path = "/data/test/TransListenerCoreTest_HandleCopyFailure_002.txt"; int32_t fd = open(path.c_str(), O_CREAT | O_RDWR, 0644); + if (fd < 0) { + EXPECT_TRUE(false); + } close(fd); Storage::DistributedFile::HmdfsInfo info; @@ -199,7 +167,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_WaitForCopyResult_001, tes { GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_WaitForCopyResult_001"; - shared_ptr transListener(new TransListenerCore); + std::shared_ptr transListener = std::make_shared(); transListener->copyEvent_.copyResult = FAILED; int result = TransListenerCore::WaitForCopyResult(transListener.get()); EXPECT_EQ(result, 2); @@ -521,7 +489,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFileReceive_001, testing { GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFileReceive_001"; - shared_ptr transListener(new TransListenerCore); + std::shared_ptr transListener = std::make_shared(); transListener->callback_ = nullptr; auto res = transListener->OnFileReceive(0, 0); EXPECT_EQ(res, ENOMEM); @@ -540,7 +508,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFileReceive_002, testing { GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFileReceive_002"; - shared_ptr transListener(new TransListenerCore); + std::shared_ptr transListener = std::make_shared(); transListener->callback_ = make_shared(std::make_shared()); auto res = transListener->OnFileReceive(0, 0); EXPECT_EQ(res, ERRNO_NOERR); @@ -559,7 +527,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFinished_001, testing::e { GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFinished_001"; - shared_ptr transListener(new TransListenerCore); + std::shared_ptr transListener = std::make_shared(); auto res = transListener->OnFinished("sessionName"); EXPECT_EQ(res, ERRNO_NOERR); @@ -577,7 +545,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_OnFailed_001, testing::ext { GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_OnFailed_001"; - shared_ptr transListener(new TransListenerCore); + std::shared_ptr transListener = std::make_shared(); auto res = transListener->OnFailed("sessionName", 0); EXPECT_EQ(res, ERRNO_NOERR); @@ -596,12 +564,11 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, t GTEST_LOG_(INFO) << "TransListenerCoreTest-begin TransListenerCoreTest_CopyFileFromSoftBus_001"; string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; - shared_ptr transListener(new TransListenerCore); + std::shared_ptr transListener = std::make_shared(); std::shared_ptr infos(new FsFileInfos); transListener->copyEvent_.copyResult = FAILED; auto res = transListener->CopyFileFromSoftBus(srcUri, "destUri", infos, nullptr); - EXPECT_EQ(res, EIO); GTEST_LOG_(INFO) << "TransListenerCoreTest-end TransListenerCoreTest_CopyFileFromSoftBus_001"; -- Gitee From 08c1a7e7a748503c9f52aad18319fb7c4719f51f Mon Sep 17 00:00:00 2001 From: tianp Date: Thu, 26 Jun 2025 15:25:46 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E5=86=B2=E7=AA=81=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E8=A7=A3=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tianp Change-Id: I7fccd266cac2aff19ff95452a503f4f7a97e2ff5 --- interfaces/kits/js/BUILD.gn | 1 + .../mod_fs/class_watcher/fs_file_watcher.cpp | 173 ++- .../mod_fs/class_watcher/fs_file_watcher.h | 36 +- .../class_watcher/watcher_data_cache.cpp | 162 +++ .../mod_fs/class_watcher/watcher_data_cache.h | 54 + .../js/src/mod_fs/properties/watcher_core.cpp | 2 +- interfaces/test/unittest/BUILD.gn | 3 +- interfaces/test/unittest/js/BUILD.gn | 61 +- .../fs_file_watcher_mock_test.cpp | 1163 +++++++++++++++++ .../class_watcher/fs_watcher_mock_test.cpp | 264 ++++ .../inotify_mock.cpp => common/fs_err_code.h} | 21 +- .../unittest/js/mod_fs/mock/eventfd_mock.cpp | 51 + .../unittest/js/mod_fs/mock/eventfd_mock.h | 50 + .../unittest/js/mod_fs/mock/inotify_mock.cpp | 61 + .../{properties => }/mock/inotify_mock.h | 19 +- .../js/mod_fs/mock/mock_watcher_callback.h | 41 + .../unittest/js/mod_fs/mock/poll_mock.cpp | 51 + .../test/unittest/js/mod_fs/mock/poll_mock.h | 50 + .../unittest/js/mod_fs/mock/unistd_mock.cpp | 61 + .../unittest/js/mod_fs/mock/unistd_mock.h | 54 + .../mod_fs/properties/copy_core_mock_test.cpp | 37 +- .../js/mod_fs/properties/copy_core_test.cpp | 28 +- .../mod_fs/properties/open_core_mock_test.cpp | 28 +- .../properties/trans_listener_mock_test.cpp | 10 +- .../mod_fs/properties/trans_listener_test.cpp | 2 +- .../properties/watcher_core_mock_test.cpp | 225 ++++ 26 files changed, 2499 insertions(+), 209 deletions(-) create mode 100644 interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.cpp create mode 100644 interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.h create mode 100644 interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/class_watcher/fs_watcher_mock_test.cpp rename interfaces/test/unittest/js/mod_fs/{properties/mock/inotify_mock.cpp => common/fs_err_code.h} (71%) create mode 100644 interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.h create mode 100644 interfaces/test/unittest/js/mod_fs/mock/inotify_mock.cpp rename interfaces/test/unittest/js/mod_fs/{properties => }/mock/inotify_mock.h (78%) create mode 100644 interfaces/test/unittest/js/mod_fs/mock/mock_watcher_callback.h create mode 100644 interfaces/test/unittest/js/mod_fs/mock/poll_mock.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/mock/poll_mock.h create mode 100644 interfaces/test/unittest/js/mod_fs/mock/unistd_mock.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/mock/unistd_mock.h create mode 100644 interfaces/test/unittest/js/mod_fs/properties/watcher_core_mock_test.cpp diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index d76e110b2..0d0381732 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -719,6 +719,7 @@ ohos_shared_library("ani_file_fs") { "src/mod_fs/class_watcher/ani/watch_event_wrapper.cpp", "src/mod_fs/class_watcher/fs_file_watcher.cpp", "src/mod_fs/class_watcher/fs_watcher.cpp", + "src/mod_fs/class_watcher/watcher_data_cache.cpp", "src/mod_fs/fs_utils.cpp", "src/mod_fs/properties/access_core.cpp", "src/mod_fs/properties/ani/access_ani.cpp", diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp index 24e09e958..9f77d49df 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp @@ -28,12 +28,6 @@ namespace OHOS::FileManagement::ModuleFileIO { using namespace std; -mutex FsFileWatcher::watchMutex_; - -FsFileWatcher::FsFileWatcher() {} - -FsFileWatcher::~FsFileWatcher() {} - int32_t FsFileWatcher::GetNotifyId() { return notifyFd_; @@ -54,51 +48,43 @@ bool FsFileWatcher::InitNotify() return true; } -tuple FsFileWatcher::CheckEventWatched(const string &fileName, const uint32_t &event) +int32_t FsFileWatcher::StartNotify(shared_ptr info) { - int32_t wd = -1; - auto iter = wdFileNameMap_.find(fileName); - if (iter == wdFileNameMap_.end()) { - return { false, wd }; + if (!info) { + HILOGE("Invalid param: info"); + return EINVAL; } - wd = iter->second.first; - if ((iter->second.second & event) == event) { - return { true, wd }; - } - return { false, wd }; -} -int32_t FsFileWatcher::StartNotify(shared_ptr info) -{ - lock_guard lock(watchMutex_); if (notifyFd_ < 0) { HILOGE("Failed to start notify notifyFd_:%{public}d", notifyFd_); return EIO; } - auto [isWatched, wd] = CheckEventWatched(info->fileName, info->events); + auto [isWatched, wd] = dataCache_.FindWatchedWd(info->fileName, info->events); if (isWatched && wd > 0) { info->wd = wd; return ERRNO_NOERR; } + uint32_t watchEvents = 0; if (wd != -1) { - watchEvents = wdFileNameMap_[info->fileName].second | info->events; + watchEvents = dataCache_.GetFileEvents(info->fileName) | info->events; } else { watchEvents = info->events; } + int32_t newWd = inotify_add_watch(notifyFd_, info->fileName.c_str(), watchEvents); if (newWd < 0) { HILOGE("Failed to start notify errCode:%{public}d", errno); return errno; } + info->wd = newWd; - wdFileNameMap_[info->fileName].first = newWd; - wdFileNameMap_[info->fileName].second = watchEvents; + dataCache_.UpdateWatchedEvents(info->fileName, newWd, watchEvents); return ERRNO_NOERR; } -int32_t FsFileWatcher::NotifyToWatchNewEvents(const string &fileName, const int32_t &wd, const uint32_t &watchEvents) +int32_t FsFileWatcher::NotifyToWatchNewEvents(const string &fileName, int32_t wd, uint32_t watchEvents) { int32_t newWd = inotify_add_watch(notifyFd_, fileName.c_str(), watchEvents); if (newWd < 0) { @@ -110,7 +96,8 @@ int32_t FsFileWatcher::NotifyToWatchNewEvents(const string &fileName, const int3 HILOGE("New notify wd is error"); return EIO; } - wdFileNameMap_[fileName].second = watchEvents; + + dataCache_.UpdateWatchedEvents(fileName, wd, watchEvents); return ERRNO_NOERR; } @@ -118,13 +105,14 @@ int32_t FsFileWatcher::CloseNotifyFd() { int32_t closeRet = ERRNO_NOERR; - if (watcherInfoSet_.size() == 0) { + if (!dataCache_.HasWatcherInfo()) { run_ = false; closeRet = close(notifyFd_); if (closeRet != 0) { HILOGE("Failed to stop notify close fd errCode:%{public}d", errno); } notifyFd_ = -1; + closeRet = close(eventFd_); if (closeRet != 0) { HILOGE("Failed to close eventfd errCode:%{public}d", errno); @@ -137,7 +125,7 @@ int32_t FsFileWatcher::CloseNotifyFd() return closeRet; } -int FsFileWatcher::CloseNotifyFdLocked() +int32_t FsFileWatcher::CloseNotifyFdLocked() { { lock_guard lock(readMutex_); @@ -152,20 +140,28 @@ int FsFileWatcher::CloseNotifyFdLocked() int32_t FsFileWatcher::StopNotify(shared_ptr info) { - unique_lock lock(watchMutex_); + if (!info) { + HILOGE("Invalid param: info"); + return EINVAL; + } + if (notifyFd_ < 0) { HILOGE("Failed to stop notify notifyFd_:%{public}d", notifyFd_); return EIO; } - uint32_t newEvents = RemoveWatcherInfo(info); - if (newEvents > 0) { + + uint32_t remainingEvents = RemoveWatcherInfo(info); + if (remainingEvents > 0) { + // There are still events remaining to be listened for. if (access(info->fileName.c_str(), F_OK) == 0) { - return NotifyToWatchNewEvents(info->fileName, info->wd, newEvents); + return NotifyToWatchNewEvents(info->fileName, info->wd, remainingEvents); } HILOGE("The Watched file does not exist, and the remaining monitored events will be invalid."); return ERRNO_NOERR; } - int oldWd = -1; + + // No events remain to be listened for, and proceed to the file watch removal process. + int32_t oldWd = -1; { lock_guard lock(readMutex_); if (!(closed_ && reading_)) { @@ -174,16 +170,18 @@ int32_t FsFileWatcher::StopNotify(shared_ptr info) HILOGE("rm watch fail"); } } + if (oldWd == -1) { - int rmErr = errno; + int32_t rmErr = errno; if (access(info->fileName.c_str(), F_OK) == 0) { HILOGE("Failed to stop notify errCode:%{public}d", rmErr); - wdFileNameMap_.erase(info->fileName); + dataCache_.RemoveFileWatcher(info->fileName); CloseNotifyFdLocked(); return rmErr; } } - wdFileNameMap_.erase(info->fileName); + + dataCache_.RemoveFileWatcher(info->fileName); return CloseNotifyFdLocked(); } @@ -193,6 +191,7 @@ void FsFileWatcher::ReadNotifyEvent() int32_t index = 0; char buf[BUF_SIZE] = { 0 }; struct inotify_event *event = nullptr; + do { len = read(notifyFd_, &buf, sizeof(buf)); if (len < 0 && errno != EINTR) { @@ -200,6 +199,7 @@ void FsFileWatcher::ReadNotifyEvent() break; } } while (len < 0); + while (index < len) { event = reinterpret_cast(buf + index); NotifyEvent(event); @@ -217,7 +217,9 @@ void FsFileWatcher::ReadNotifyEventLocked() } reading_ = true; } + ReadNotifyEvent(); + { lock_guard lock(readMutex_); reading_ = false; @@ -243,95 +245,78 @@ void FsFileWatcher::GetNotifyEvent() if (run_) { return; } + run_ = true; nfds_t nfds = 2; - struct pollfd fds[2]; + struct pollfd fds[2] = { { -1 } }; fds[0].fd = eventFd_; - fds[0].events = 0; + fds[0].events = POLLIN; fds[1].fd = notifyFd_; fds[1].events = POLLIN; int32_t ret = 0; + while (run_) { - ret = poll(fds, nfds, -1); + ret = poll(fds, nfds, pollTimeoutMs); if (ret > 0) { if (static_cast(fds[0].revents) & POLLNVAL) { run_ = false; - return; + break; + } + if (static_cast(fds[0].revents) & POLLIN) { + run_ = false; + break; } if (static_cast(fds[1].revents) & POLLIN) { ReadNotifyEventLocked(); } - } else if (ret < 0 && errno == EINTR) { - continue; - } else { + } else if (ret < 0 && errno != EINTR) { HILOGE("Failed to poll NotifyFd, errno=%{public}d", errno); - return; + break; } + // Ignore cases where poll returns 0 (timeout) or EINTR (interrupted system call) } } -bool FsFileWatcher::AddWatcherInfo(const string &fileName, shared_ptr info) +bool FsFileWatcher::AddWatcherInfo(shared_ptr info) { - for (auto &iter : watcherInfoSet_) { - if (iter->fileName == info->fileName && iter->events == info->events) { - bool isSame = iter->callback->IsStrictEquals(info->callback); - if (isSame) { - HILOGE("Faile to add watcher, fileName:%{public}s the callback is same", fileName.c_str()); - return false; - } - } + if (!info) { + HILOGE("Invalid param: info"); + return false; } - watcherInfoSet_.insert(info); - return true; + return dataCache_.AddWatcherInfo(info); } uint32_t FsFileWatcher::RemoveWatcherInfo(shared_ptr info) { - watcherInfoSet_.erase(info); - uint32_t otherEvents = 0; - for (const auto &iter : watcherInfoSet_) { - if (iter->fileName == info->fileName && iter->wd > 0) { - otherEvents |= iter->events; - } + if (!info) { + HILOGE("Invalid param: info"); + return EINVAL; } - return otherEvents; + return dataCache_.RemoveWatcherInfo(info); } -static bool CheckIncludeEvent(const uint32_t &mask, const uint32_t &event) +void FsFileWatcher::NotifyEvent(const struct inotify_event *event) { - if ((mask & event) > 0) { - return true; + if (!event) { + HILOGE("Invalid inotify event"); + return; } - return false; -} -void FsFileWatcher::NotifyEvent(const struct inotify_event *event) -{ - lock_guard lock(watchMutex_); - string tempFileName; - auto found = find_if(wdFileNameMap_.begin(), wdFileNameMap_.end(), - [event](const pair> &iter) { return iter.second.first == event->wd; }); - if (found != wdFileNameMap_.end()) { - tempFileName = found->first; + auto [matched, fileName, watcherInfos] = dataCache_.FindWatcherInfos(event->wd, event->mask); + if (!matched) { + HILOGE("Cannot find matched watcherInfos"); + return; } - for (const auto &iter : watcherInfoSet_) { - string fileName = tempFileName; - uint32_t watchEvent = 0; - if ((iter->fileName == fileName) && (iter->wd > 0)) { - watchEvent = iter->events; - } - if (!CheckIncludeEvent(event->mask, watchEvent)) { - continue; - } + for (const auto &info : watcherInfos) { if (event->len > 0) { fileName += "/" + string(event->name); } - iter->TriggerCallback(fileName, event->mask & IN_ALL_EVENTS, event->cookie); + info->TriggerCallback(fileName, event->mask & IN_ALL_EVENTS, event->cookie); } } -bool FsFileWatcher::CheckEventValid(const uint32_t &event) +bool FsFileWatcher::CheckEventValid(uint32_t event) { if ((event & IN_ALL_EVENTS) == event) { return true; @@ -344,12 +329,20 @@ bool FsFileWatcher::CheckEventValid(const uint32_t &event) void FsFileWatcher::DestroyTaskThead() { if (taskThead_.joinable()) { - taskThead_.join(); + if (taskThead_.get_id() != std::this_thread::get_id()) { + taskThead_.join(); + } else { + taskThead_.detach(); + } } - lock_guard lock(taskMutex_); - if (taskRunning_) { - taskRunning_ = false; + { + lock_guard lock(taskMutex_); + if (taskRunning_) { + taskRunning_ = false; + run_ = false; + } } + dataCache_.ClearCache(); } } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.h b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.h index 17be3a40a..57b83d331 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.h +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.h @@ -18,46 +18,48 @@ #include #include #include -#include -#include #include #include "filemgmt_libfs.h" #include "fs_watch_entity.h" #include "singleton.h" +#include "watcher_data_cache.h" namespace OHOS::FileManagement::ModuleFileIO { using namespace std; -constexpr int BUF_SIZE = 1024; +constexpr int32_t BUF_SIZE = 1024; class FsFileWatcher : public Singleton { public: - FsFileWatcher(); - ~FsFileWatcher(); int32_t GetNotifyId(); bool InitNotify(); - int StartNotify(shared_ptr info); - int StopNotify(shared_ptr info); + int32_t StartNotify(shared_ptr info); + int32_t StopNotify(shared_ptr info); void GetNotifyEvent(); void AsyncGetNotifyEvent(); - bool AddWatcherInfo(const string &fileName, shared_ptr info); - bool CheckEventValid(const uint32_t &event); + bool AddWatcherInfo(shared_ptr info); + bool CheckEventValid(uint32_t event); + +public: + FsFileWatcher() = default; + ~FsFileWatcher() = default; + FsFileWatcher(const FsFileWatcher &) = delete; + FsFileWatcher &operator=(const FsFileWatcher &) = delete; private: uint32_t RemoveWatcherInfo(shared_ptr info); - tuple CheckEventWatched(const string &fileName, const uint32_t &event); void NotifyEvent(const struct inotify_event *event); - int CloseNotifyFd(); - int CloseNotifyFdLocked(); - int NotifyToWatchNewEvents(const string &fileName, const int &wd, const uint32_t &watchEvents); + int32_t CloseNotifyFd(); + int32_t CloseNotifyFdLocked(); + int32_t NotifyToWatchNewEvents(const string &fileName, int32_t wd, uint32_t watchEvents); void ReadNotifyEvent(); void ReadNotifyEventLocked(); void DestroyTaskThead(); private: - static mutex watchMutex_; + static constexpr int32_t pollTimeoutMs = 500; mutex taskMutex_; mutex readMutex_; @@ -70,11 +72,7 @@ private: bool closed_ = false; int32_t notifyFd_ = -1; int32_t eventFd_ = -1; - unordered_set> watcherInfoSet_; - unordered_map> wdFileNameMap_; - - FsFileWatcher(const FsFileWatcher &) = delete; - FsFileWatcher &operator=(const FsFileWatcher &) = delete; + WatcherDataCache dataCache_; }; } // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.cpp new file mode 100644 index 000000000..83b5e2a51 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.cpp @@ -0,0 +1,162 @@ +/* + * 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 "watcher_data_cache.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +bool WatcherDataCache::AddWatcherInfo(std::shared_ptr info) +{ + std::lock_guard lock(cacheMutex_); + for (auto &iter : watcherInfoCache_) { + if (iter->fileName == info->fileName && iter->events == info->events) { + bool isSame = iter->callback->IsStrictEquals(info->callback); + if (isSame) { + HILOGE("Failed to add watcher, fileName:%{private}s the callback is same", info->fileName.c_str()); + return false; + } + } + } + watcherInfoCache_.push_back(info); + wdFileNameCache_[info->fileName] = std::make_pair(info->wd, info->events); + return true; +} + +uint32_t WatcherDataCache::RemoveWatcherInfo(std::shared_ptr info) +{ + std::lock_guard lock(cacheMutex_); + auto it = std::find(watcherInfoCache_.begin(), watcherInfoCache_.end(), info); + if (it != watcherInfoCache_.end()) { + watcherInfoCache_.erase(it); + } + + uint32_t remainingEvents = 0; + for (const auto &iter : watcherInfoCache_) { + if (iter->fileName == info->fileName && iter->wd > 0) { + remainingEvents |= iter->events; + } + } + + return remainingEvents; +} + +bool WatcherDataCache::RemoveFileWatcher(const std::string &fileName) +{ + std::lock_guard lock(cacheMutex_); + + auto iter = wdFileNameCache_.find(fileName); + if (iter == wdFileNameCache_.end()) { + return false; + } + wdFileNameCache_.erase(iter); + + watcherInfoCache_.erase(std::remove_if(watcherInfoCache_.begin(), watcherInfoCache_.end(), + [&fileName](const std::shared_ptr &info) { + return info->fileName == fileName; + }), watcherInfoCache_.end()); + + return true; +} + +std::tuple WatcherDataCache::FindWatchedWd(const std::string &fileName, uint32_t event) +{ + std::lock_guard lock(cacheMutex_); + + int32_t wd = -1; + auto iter = wdFileNameCache_.find(fileName); + if (iter == wdFileNameCache_.end()) { + return { false, wd }; + } + + wd = iter->second.first; + if ((iter->second.second & event) == event) { + return { true, wd }; + } + + return { false, wd }; +} + +bool WatcherDataCache::UpdateWatchedEvents(const std::string &fileName, int32_t wd, uint32_t events) +{ + std::lock_guard lock(cacheMutex_); + auto iter = wdFileNameCache_.find(fileName); + if (iter == wdFileNameCache_.end()) { + return false; + } + + iter->second = std::make_pair(wd, events); + return true; +} + +static bool CheckIncludeEvent(uint32_t mask, uint32_t event) +{ + return (mask & event) > 0; +} + +std::tuple>> WatcherDataCache::FindWatcherInfos( + int32_t wd, uint32_t eventMask) +{ + std::lock_guard lock(cacheMutex_); + std::string fileName; + bool found = false; + for (const auto &[key, val] : wdFileNameCache_) { + if (val.first == wd) { + fileName = key; + found = true; + break; + } + } + + if (!found) { + return { false, "", {} }; + } + + std::vector> matchedInfos; + for (const auto &info : watcherInfoCache_) { + uint32_t watchEvent = 0; + if ((info->fileName == fileName) && (info->wd > 0)) { + watchEvent = info->events; + } + if (CheckIncludeEvent(eventMask, watchEvent)) { + matchedInfos.push_back(info); + } + } + return { !matchedInfos.empty(), fileName, matchedInfos }; +} + +uint32_t WatcherDataCache::GetFileEvents(const std::string &fileName) +{ + std::lock_guard lock(cacheMutex_); + auto iter = wdFileNameCache_.find(fileName); + if (iter == wdFileNameCache_.end()) { + return 0; + } + return iter->second.second; +} + +bool WatcherDataCache::HasWatcherInfo() const +{ + std::lock_guard lock(cacheMutex_); + return !watcherInfoCache_.empty(); +} + +void WatcherDataCache::ClearCache() +{ + std::lock_guard lock(cacheMutex_); + watcherInfoCache_.clear(); + wdFileNameCache_.clear(); +} + +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.h b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.h new file mode 100644 index 000000000..e18d584f1 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_data_cache.h @@ -0,0 +1,54 @@ +/* + * 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 INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_WATCHER_DATA_CACHE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_WATCHER_DATA_CACHE_H + +#include +#include +#include +#include +#include + +#include "fs_watch_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +class WatcherDataCache { +public: + bool AddWatcherInfo(std::shared_ptr info); + uint32_t RemoveWatcherInfo(std::shared_ptr info); + bool RemoveFileWatcher(const std::string &fileName); + std::tuple FindWatchedWd(const std::string &fileName, uint32_t event); + bool UpdateWatchedEvents(const std::string &fileName, int32_t wd, uint32_t events); + std::tuple>> FindWatcherInfos( + int32_t wd, uint32_t eventMask); + uint32_t GetFileEvents(const std::string &fileName); + bool HasWatcherInfo() const; + void ClearCache(); + +public: + WatcherDataCache() = default; + ~WatcherDataCache() = default; + WatcherDataCache(const WatcherDataCache &) = delete; + WatcherDataCache &operator=(const WatcherDataCache &) = delete; + +private: + mutable std::mutex cacheMutex_; + std::vector> watcherInfoCache_; + std::unordered_map> wdFileNameCache_; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_WATCHER_DATA_CACHE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher_core.cpp b/interfaces/kits/js/src/mod_fs/properties/watcher_core.cpp index 382f494ec..1ea4a713a 100644 --- a/interfaces/kits/js/src/mod_fs/properties/watcher_core.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/watcher_core.cpp @@ -98,7 +98,7 @@ FsResult WatcherCore::DoCreateWatcher( watchEntity->data_ = info; - bool ret = FsFileWatcher::GetInstance().AddWatcherInfo(info->fileName, info); + bool ret = FsFileWatcher::GetInstance().AddWatcherInfo(info); if (!ret) { HILOGE("Failed to add watcher info."); return FsResult::Error(EINVAL); diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 527a36cb5..76ae91222 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Copyright (c) 2022-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 @@ -16,7 +16,6 @@ group("file_api_unittest") { deps = [ "class_file:class_file_test", "filemgmt_libn_test:filemgmt_libn_test", - "js:ani_file_environment_test", "js:ani_file_fs_mock_test", "js:ani_file_fs_test", "js:ani_file_hash_test", diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index b3350ec9d..a3e0eb56d 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -38,7 +38,6 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/class_stat/fs_stat_test.cpp", "mod_fs/class_stream/fs_stream_test.cpp", "mod_fs/class_tasksignal/fs_task_signal_test.cpp", - "mod_fs/properties/access_core_test.cpp", "mod_fs/properties/close_core_test.cpp", "mod_fs/properties/copy_core_test.cpp", "mod_fs/properties/copy_dir_core_test.cpp", @@ -48,23 +47,18 @@ ohos_unittest("ani_file_fs_test") { "mod_fs/properties/listfile_core_test.cpp", "mod_fs/properties/lstat_core_test.cpp", "mod_fs/properties/open_core_test.cpp", - "mod_fs/properties/read_core_test.cpp", "mod_fs/properties/read_lines_core_test.cpp", "mod_fs/properties/read_text_core_test.cpp", - "mod_fs/properties/rmdir_core_test.cpp", "mod_fs/properties/trans_listener_test.cpp", - "mod_fs/properties/truncate_core_test.cpp", - "mod_fs/properties/utimes_core_test.cpp", - "mod_fs/properties/write_core_test.cpp", ] deps = [ + "${file_api_path}/interfaces/kits/js:ani_file_fs", "${file_api_path}/interfaces/kits/native:remote_uri_native", "${file_api_path}/interfaces/kits/native:task_signal_native", "${file_api_path}/interfaces/kits/rust:rust_file", "${utils_path}/filemgmt_libfs:filemgmt_libfs", "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", - "${file_api_path}/interfaces/kits/js:ani_file_fs", ] external_deps = [ @@ -79,9 +73,7 @@ ohos_unittest("ani_file_fs_test") { "libuv:uv", ] - defines = [ - "private=public", - ] + defines = [ "private=public" ] } ohos_unittest("ani_file_fs_mock_test") { @@ -98,9 +90,12 @@ ohos_unittest("ani_file_fs_mock_test") { "${file_api_path}/interfaces/kits/js/src/mod_fs/class_stat", "${file_api_path}/interfaces/kits/js/src/mod_fs/class_stream", "${file_api_path}/interfaces/kits/js/src/mod_fs/class_tasksignal", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher", "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/copy_listener", "${file_api_path}/interfaces/test/unittest/js/mod_fs/class_stream/mock", + "${file_api_path}/interfaces/test/unittest/js/mod_fs/common", + "${file_api_path}/interfaces/test/unittest/js/mod_fs/mock", "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock", ] @@ -110,33 +105,31 @@ ohos_unittest("ani_file_fs_mock_test") { "mod_fs/class_stat/fs_stat_mock_test.cpp", "mod_fs/class_stream/fs_stream_mock_test.cpp", "mod_fs/class_stream/mock/c_mock.cpp", - "mod_fs/properties/access_core_mock_test.cpp", + "mod_fs/class_watcher/fs_file_watcher_mock_test.cpp", + "mod_fs/class_watcher/fs_watcher_mock_test.cpp", + "mod_fs/mock/eventfd_mock.cpp", + "mod_fs/mock/inotify_mock.cpp", + "mod_fs/mock/poll_mock.cpp", + "mod_fs/mock/unistd_mock.cpp", "mod_fs/properties/copy_core_mock_test.cpp", "mod_fs/properties/create_randomaccessfile_core_mock_test.cpp", - "mod_fs/properties/dup_core_mock_test.cpp", "mod_fs/properties/fdatasync_core_mock_test.cpp", "mod_fs/properties/lstat_core_mock_test.cpp", - "mod_fs/properties/mock/inotify_mock.cpp", "mod_fs/properties/mock/system_mock.cpp", "mod_fs/properties/mock/uv_fs_mock.cpp", "mod_fs/properties/open_core_mock_test.cpp", - "mod_fs/properties/read_core_mock_test.cpp", "mod_fs/properties/read_lines_core_mock_test.cpp", - "mod_fs/properties/symlink_core_mock_test.cpp", "mod_fs/properties/trans_listener_mock_test.cpp", - "mod_fs/properties/truncate_core_mock_test.cpp", - "mod_fs/properties/unlink_core_mock_test.cpp", - "mod_fs/properties/utimes_core_mock_test.cpp", - "mod_fs/properties/xattr_core_mock_test.cpp", + "mod_fs/properties/watcher_core_mock_test.cpp", ] deps = [ + "${file_api_path}/interfaces/kits/js:ani_file_fs", "${file_api_path}/interfaces/kits/native:remote_uri_native", "${file_api_path}/interfaces/kits/native:task_signal_native", "${file_api_path}/interfaces/kits/rust:rust_file", "${utils_path}/filemgmt_libfs:filemgmt_libfs", "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", - "${file_api_path}/interfaces/kits/js:ani_file_fs", ] external_deps = [ @@ -163,9 +156,7 @@ ohos_unittest("ani_file_hash_test") { resource_config_file = "../resource/ohos_test.xml" - sources = [ - "mod_hash/hash_core_test.cpp", - ] + sources = [ "mod_hash/hash_core_test.cpp" ] include_dirs = [ "mock/libuv", @@ -173,17 +164,17 @@ ohos_unittest("ani_file_hash_test") { ] deps = [ - "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", - "${utils_path}/filemgmt_libfs:filemgmt_libfs", "${file_api_path}/interfaces/kits/js:ani_file_hash", + "${utils_path}/filemgmt_libfs:filemgmt_libfs", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", ] external_deps = [ "c_utils:utils", - "hilog:libhilog", - "libuv:uv", "googletest:gmock_main", "googletest:gtest_main", + "hilog:libhilog", + "libuv:uv", ] } @@ -192,9 +183,7 @@ ohos_unittest("ani_file_securitylabel_test") { resource_config_file = "../resource/ohos_test.xml" - sources = [ - "mod_securitylabel/securitylabel_core_test.cpp", - ] + sources = [ "mod_securitylabel/securitylabel_core_test.cpp" ] include_dirs = [ "mock/libuv", @@ -203,16 +192,16 @@ ohos_unittest("ani_file_securitylabel_test") { deps = [ "${file_api_path}/interfaces/kits/js:ani_file_securitylabel", - "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", "${utils_path}/filemgmt_libfs:filemgmt_libfs", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", ] external_deps = [ "c_utils:utils", - "hilog:libhilog", - "libuv:uv", "googletest:gmock_main", "googletest:gtest_main", + "hilog:libhilog", + "libuv:uv", ] } @@ -221,9 +210,7 @@ ohos_unittest("ani_file_statvfs_test") { resource_config_file = "../resource/ohos_test.xml" - sources = [ - "mod_statvfs/statvfs_core_test.cpp", - ] + sources = [ "mod_statvfs/statvfs_core_test.cpp" ] include_dirs = [ "mock/libuv", @@ -243,4 +230,4 @@ ohos_unittest("ani_file_statvfs_test") { "hilog:libhilog", "libuv:uv", ] -} \ No newline at end of file +} diff --git a/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp new file mode 100644 index 000000000..adf4db15e --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp @@ -0,0 +1,1163 @@ +/* + * 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 "eventfd_mock.h" +#include "filemgmt_libhilog.h" +#include "fs_file_watcher.h" +#include "inotify_mock.h" +#include "mock_watcher_callback.h" +#include "poll_mock.h" +#include "securec.h" +#include "unistd_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class FsFileWatcherMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void FsFileWatcherMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FsFileWatcherMockTest::TearDownTestCase(void) +{ + EventfdMock::DestroyMock(); + InotifyMock::DestroyMock(); + PollMock::DestroyMock(); + UnistdMock::DestroyMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FsFileWatcherMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + errno = 0; // Reset errno +} + +void FsFileWatcherMockTest::TearDown(void) +{ + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.taskRunning_ = false; + watcher.run_ = false; + watcher.reading_ = false; + watcher.closed_ = false; + watcher.notifyFd_ = -1; + watcher.eventFd_ = -1; + watcher.dataCache_.ClearCache(); + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyId_001 + * @tc.desc: Test function of FsFileWatcher::GetNotifyId interface. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyId_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyId_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + int32_t expected = -1; + // Do testing + int32_t result = watcher.GetNotifyId(); + // Verify results + EXPECT_EQ(result, expected); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyId_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_InitNotify_001 + * @tc.desc: Test function of FsFileWatcher::InitNotify interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_InitNotify_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_InitNotify_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Set mock behaviors + auto eventfdMock = EventfdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::Return(1)); + EXPECT_CALL(*eventfdMock, eventfd(testing::_, testing::_)).Times(1).WillOnce(testing::Return(2)); + // Do testing + bool result = watcher.InitNotify(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + testing::Mock::VerifyAndClearExpectations(eventfdMock.get()); + EXPECT_TRUE(result); + EXPECT_EQ(watcher.notifyFd_, 1); + EXPECT_EQ(watcher.eventFd_, 2); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_InitNotify_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_InitNotify_002 + * @tc.desc: Test function of FsFileWatcher::InitNotify interface for FAILURE when inotify_init fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_InitNotify_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_InitNotify_002"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + bool result = watcher.InitNotify(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_FALSE(result); + EXPECT_EQ(watcher.notifyFd_, -1); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_InitNotify_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_InitNotify_003 + * @tc.desc: Test function of FsFileWatcher::InitNotify interface for FAILURE when eventfd fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_InitNotify_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_InitNotify_003"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + auto eventfdMock = EventfdMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::Return(1)); + EXPECT_CALL(*eventfdMock, eventfd(testing::_, testing::_)).Times(1).WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + bool result = watcher.InitNotify(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + testing::Mock::VerifyAndClearExpectations(eventfdMock.get()); + EXPECT_FALSE(result); + EXPECT_EQ(watcher.notifyFd_, 1); + EXPECT_EQ(watcher.eventFd_, -1); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_InitNotify_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StartNotify_001 + * @tc.desc: Test function of FsFileWatcher::StartNotify interface for SUCCESS when path is not watched. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StartNotify_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StartNotify_001"; + // Prepare test parameters + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StartNotify_001"; + info->events = IN_CREATE | IN_DELETE; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + // Set mock behaviors + int32_t expectedWd = 100; + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(expectedWd)); + // Do testing + int32_t result = watcher.StartNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + EXPECT_EQ(info->wd, expectedWd); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StartNotify_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StartNotify_002 + * @tc.desc: Test function of FsFileWatcher::StartNotify interface for SUCCESS when path is already watched with same + * events. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StartNotify_002, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StartNotify_002"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StartNotify_002"; + info->events = IN_CREATE | IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)).Times(0); + // Do testing + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + int32_t result = watcher.StartNotify(info); + // Verify results + EXPECT_EQ(result, ERRNO_NOERR); + EXPECT_EQ(info->wd, expectedWd); +} + +/** + * @tc.name: FsFileWatcherMockTest_StartNotify_003 + * @tc.desc: Test function of FsFileWatcher::StartNotify interface for FAILURE when info is nullptr. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StartNotify_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StartNotify_003"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Do testing with nullptr parameter + int32_t result = watcher.StartNotify(nullptr); + // Verify results + EXPECT_EQ(result, EINVAL); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StartNotify_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StartNotify_004 + * @tc.desc: Test function of FsFileWatcher::StartNotify interface for FAILURE when notifyFd_ is invalid. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StartNotify_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StartNotify_004"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = -1; // Invalid notifyFd + // Build test parameters + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StartNotify_004"; + info->events = IN_CREATE; + // Do testing + int32_t result = watcher.StartNotify(info); + // Verify results + EXPECT_EQ(result, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StartNotify_004"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StartNotify_005 + * @tc.desc: Test function of FsFileWatcher::StartNotify interface for FAILURE when inotify_add_watch fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StartNotify_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StartNotify_005"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + // Build test parameters + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StartNotify_005"; + info->events = IN_DELETE; + // Set mock behaviors for inotify_add_watch failure + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + int32_t result = watcher.StartNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StartNotify_005"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_001 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_001"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_001"; + info->events = IN_CREATE | IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(0); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(2).WillRepeatedly(testing::Return(0)); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_002 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for FAILURE when info is nullptr. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_002"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Do testing + int32_t result = watcher.StopNotify(nullptr); + // Verify results + EXPECT_EQ(result, EINVAL); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_003 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for FAILURE when notifyFd_ is invalid. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_003"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = -1; // Invalid notifyFd + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_003"; + info->events = IN_CREATE; + info->wd = expectedWd; + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + EXPECT_EQ(result, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_004 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for FAILURE when inotify_rm_watch fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_004"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_004"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(2).WillRepeatedly(testing::Return(0)); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_004"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_005 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for SUCCESS when rm watch fail. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_005"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_005"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set rm watch fail condition + watcher.closed_ = true; + watcher.reading_ = true; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(1).WillOnce(testing::Return(1)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(0); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_005"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_006 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for SUCCESS when having remainingEvents but access + * file failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_006"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_006"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "/test/FsFileWatcherMockTest_StopNotify_006"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = expectedWd; + watcher.dataCache_.AddWatcherInfo(remainingInfo); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(1).WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(0); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_006"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_007 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for SUCCESS when having remainingEvents and + * NotifyToWatchNewEvents success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_007, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_007"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_007"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "/test/FsFileWatcherMockTest_StopNotify_007"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = expectedWd; + watcher.dataCache_.AddWatcherInfo(remainingInfo); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(expectedWd)); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_007"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_008 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for FAILURE when having remainingEvents but + * NotifyToWatchNewEvents fails for inotify_add_watch fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_008, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_008"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_008"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "/test/FsFileWatcherMockTest_StopNotify_008"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = expectedWd; + watcher.dataCache_.AddWatcherInfo(remainingInfo); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_008"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_009 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for FAILURE when having remainingEvents but + * NotifyToWatchNewEvents fails for inotify_add_watch return another wd. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_009, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_009"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_009"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "/test/FsFileWatcherMockTest_StopNotify_009"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = expectedWd; + watcher.dataCache_.AddWatcherInfo(remainingInfo); + // Set mock behaviors + int32_t unexpectedWd = 200; + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(0); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(unexpectedWd)); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_009"; +} + +/** + * @tc.name: FsFileWatcherMockTest_StopNotify_010 + * @tc.desc: Test function of FsFileWatcher::StopNotify interface for FAILURE when CloseNotifyFd fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StopNotify_010, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StopNotify_010"; + // Prepare test parameters + int32_t expectedWd = 100; + auto info = std::make_shared(nullptr); + info->fileName = "/test/FsFileWatcherMockTest_StopNotify_010"; + info->events = IN_DELETE; + info->wd = expectedWd; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.eventFd_ = 1; + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).Times(0); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(2).WillRepeatedly(testing::Return(EIO)); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + // Do testing + int32_t result = watcher.StopNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, EIO); + EXPECT_EQ(watcher.notifyFd_, -1); + EXPECT_EQ(watcher.eventFd_, -1); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StopNotify_010"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_001 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when run_ is true. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = true; + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)).Times(0); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_002 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when poll returns ret > 0 and fds[0].revents has + * POLLNVAL. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_002"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = false; + watcher.notifyFd_ = 1; + watcher.eventFd_ = 2; + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([](struct pollfd *fds, nfds_t n, int timeout) { + fds[0].revents = POLLNVAL; + return 1; + }); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_FALSE(watcher.run_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_003 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when poll returns ret > 0 and fds[0].revents has + * POLLIN. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_003"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = false; + watcher.notifyFd_ = 1; + watcher.eventFd_ = 2; + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([](struct pollfd *fds, nfds_t n, int timeout) { + fds[0].revents = POLLIN; + return 1; + }); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_FALSE(watcher.run_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_004 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when poll returns ret > 0 and fds[1].revents has + * POLLIN. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_004"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = false; + watcher.notifyFd_ = 1; + watcher.eventFd_ = 2; + watcher.closed_ = true; // Avoid calling ReadNotifyEvent + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([&watcher](struct pollfd *fds, nfds_t n, int timeout) { + fds[1].revents = POLLIN; + watcher.run_ = false; // Ensure the loop will exit + return 1; + }); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_FALSE(watcher.run_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_004"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_005 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when poll returns ret == 0. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_005"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = false; + watcher.notifyFd_ = 1; + watcher.eventFd_ = 2; + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([&watcher](struct pollfd *fds, nfds_t n, int timeout) { + watcher.run_ = false; // Ensure the loop will exit + return 0; + }); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_FALSE(watcher.run_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_005"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_006 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when poll returns ret < 0 and errno == EINTR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_006"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = false; + watcher.notifyFd_ = 1; + watcher.eventFd_ = 2; + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([&watcher](struct pollfd *fds, nfds_t n, int timeout) { + errno = EINTR; + watcher.run_ = false; // Ensure the loop will exit + return -1; + }); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_FALSE(watcher.run_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_006"; +} + +/** + * @tc.name: FsFileWatcherMockTest_GetNotifyEvent_007 + * @tc.desc: Test function of FsFileWatcher::GetNotifyEvent interface when poll returns ret < 0 and errno != EINTR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_GetNotifyEvent_007, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_GetNotifyEvent_007"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.run_ = false; + watcher.notifyFd_ = 1; + watcher.eventFd_ = 2; + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([&watcher](struct pollfd *fds, nfds_t n, int timeout) { + errno = EIO; + watcher.run_ = false; // Ensure the loop will exit + return -1; + }); + // Do testing + watcher.GetNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_FALSE(watcher.run_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_GetNotifyEvent_007"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEventLocked_001 + * @tc.desc: Test ReadNotifyEventLocked when closed_ is false. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEventLocked_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEventLocked_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.closed_ = false; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(0)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(0); + // Do testing + watcher.ReadNotifyEventLocked(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_FALSE(watcher.reading_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEventLocked_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEventLocked_002 + * @tc.desc: Test ReadNotifyEventLocked when close after read. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEventLocked_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEventLocked_002"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.closed_ = false; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([&watcher](int fd, void *buf, size_t count) { + errno = EIO; + watcher.closed_ = true; // Set close after read condition + return 0; + }); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(2).WillRepeatedly(testing::Return(0)); + // Do testing + watcher.ReadNotifyEventLocked(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_FALSE(watcher.closed_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEventLocked_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_001 + * @tc.desc: Test function of FsFileWatcher::ReadNotifyEvent interface for SUCCESS when read valid event data. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + int32_t len = static_cast(sizeof(struct inotify_event)); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).Times(1).WillOnce(testing::Return(len)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_002 + * @tc.desc: Test function of FsFileWatcher::ReadNotifyEvent interface for FAILURE when read returns -1. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_002"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_EQ(errno, EIO); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_ReadNotifyEvent_003 + * @tc.desc: Test function of FsFileWatcher::ReadNotifyEvent interface for SUCCESS when read returns 0 (EOF). + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_ReadNotifyEvent_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_ReadNotifyEvent_003"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(0, 0)); + // Do testing + watcher.ReadNotifyEvent(); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_EQ(errno, 0); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_ReadNotifyEvent_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_NotifyEvent_001 + * @tc.desc: Test function of FsFileWatcher::NotifyEvent interface for SUCCESS when valid event without filename. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_NotifyEvent_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_NotifyEvent_001"; + // Prepare test parameters + int32_t expectedWd = 100; + uint32_t mask = IN_CREATE; + struct inotify_event event = { .wd = expectedWd, .mask = mask, .cookie = 0, .len = 0 }; + // Prepare test condition + auto callback = std::make_shared(); + auto info = std::make_shared(callback); + info->fileName = "/test/FsFileWatcherMockTest_NotifyEvent_001"; + info->events = mask; + info->wd = expectedWd; + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + EXPECT_CALL(*callback, InvokeCallback(testing::_, testing::_, testing::_)).Times(1); + // Do testing + watcher.NotifyEvent(&event); + // Verify results + testing::Mock::VerifyAndClearExpectations(callback.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_NotifyEvent_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_NotifyEvent_002 + * @tc.desc: Test function of FsFileWatcher::NotifyEvent interface for SUCCESS when valid event with filename. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_NotifyEvent_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_NotifyEvent_002"; + // Prepare test parameters + int32_t expectedWd = 100; + const char *name = "test.txt"; + size_t len = strlen(name); + uint32_t mask = IN_CREATE; + size_t totalSize = sizeof(struct inotify_event) + len + 1; + std::vector buffer(totalSize); + struct inotify_event *event = reinterpret_cast(buffer.data()); + event->wd = expectedWd; + event->mask = mask; + event->cookie = 0; + event->len = len + 1; + char *namePtr = reinterpret_cast(event + 1); + int ret = memcpy_s(namePtr, len + 1, name, len + 1); + if (ret != 0) { + EXPECT_EQ(ret, 0); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_NotifyEvent_002"; + return; + } + // Prepare test condition + auto callback = std::make_shared(); + auto info = std::make_shared(callback); + info->fileName = "/test/FsFileWatcherMockTest_NotifyEvent_002"; + info->events = mask; + info->wd = expectedWd; + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + EXPECT_CALL(*callback, InvokeCallback(testing::_, testing::_, testing::_)).Times(1); + // Do testing + watcher.NotifyEvent(event); + // Verify results + testing::Mock::VerifyAndClearExpectations(callback.get()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_NotifyEvent_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_NotifyEvent_003 + * @tc.desc: Test function of FsFileWatcher::NotifyEvent interface for FAILURE when event pointer is NULL. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_NotifyEvent_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_NotifyEvent_003"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Do testing + watcher.NotifyEvent(nullptr); + // Verify results + EXPECT_TRUE(watcher.dataCache_.wdFileNameCache_.empty()); + EXPECT_TRUE(watcher.dataCache_.watcherInfoCache_.empty()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_NotifyEvent_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_NotifyEvent_004 + * @tc.desc: Test function of FsFileWatcher::NotifyEvent interface for FAILURE when no matched watcher found. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_NotifyEvent_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_NotifyEvent_004"; + // Prepare test parameters + int32_t expectedWd = 100; + int32_t unexpectedWd = 200; + struct inotify_event event = { .wd = expectedWd, .mask = IN_CREATE, .cookie = 0, .len = 0 }; + // Prepare test condition + auto callback = std::make_shared(); + auto info = std::make_shared(callback); + info->fileName = "/test/FsFileWatcherMockTest_NotifyEvent_004"; + info->events = IN_MODIFY; // Not matched mask + info->wd = unexpectedWd; // Not matched wd + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + EXPECT_CALL(*callback, InvokeCallback(testing::_, testing::_, testing::_)).Times(0); + // Do testing + watcher.NotifyEvent(&event); + // Verify results + testing::Mock::VerifyAndClearExpectations(callback.get()); + EXPECT_FALSE(watcher.dataCache_.wdFileNameCache_.empty()); + EXPECT_FALSE(watcher.dataCache_.watcherInfoCache_.empty()); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_NotifyEvent_004"; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/test/unittest/js/mod_fs/class_watcher/fs_watcher_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_watcher_mock_test.cpp new file mode 100644 index 000000000..74a74b809 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_watcher_mock_test.cpp @@ -0,0 +1,264 @@ +/* + * 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 "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_err_code.h" +#include "fs_file_watcher.h" +#include "fs_watcher.h" +#include "inotify_mock.h" +#include "unistd_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class FsWatcherMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void FsWatcherMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FsWatcherMockTest::TearDownTestCase(void) +{ + InotifyMock::DestroyMock(); + UnistdMock::DestroyMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FsWatcherMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + errno = 0; // Reset errno +} + +void FsWatcherMockTest::TearDown(void) +{ + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.taskRunning_ = false; + watcher.run_ = false; + watcher.reading_ = false; + watcher.closed_ = false; + watcher.notifyFd_ = -1; + watcher.eventFd_ = -1; + watcher.dataCache_.ClearCache(); + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FsWatcherTest_Constructor_001 + * @tc.desc: Test function of FsWatcher::Constructor interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Constructor_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Constructor_001"; + // Do testing + auto result = FsWatcher::Constructor(); + // Verify results + EXPECT_TRUE(result.IsSuccess()); + auto *watcher = result.GetData().value(); + EXPECT_NE(watcher, nullptr); + if (watcher) { + auto *watcherEntity = watcher->GetWatchEntity(); + EXPECT_NE(watcherEntity, nullptr); + } + delete watcher; + watcher = nullptr; + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Constructor_001"; +} + +/** + * @tc.name: FsWatcherTest_Start_001 + * @tc.desc: Test function of FsWatcher::Start interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Start_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Start_001"; + // Prepare test condition + int32_t expectedWd = 100; + auto watchEntity = CreateUniquePtr(); + FsWatcher fsWatcher(std::move(watchEntity)); + std::shared_ptr info = std::make_shared(nullptr); + fsWatcher.GetWatchEntity()->data_ = info; + // Prepare test condition for FsFileWatcher + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + watcher.taskRunning_ = true; // Avoid starting thread + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(expectedWd)); + // Do testing + auto result = fsWatcher.Start(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_TRUE(result.IsSuccess()); + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Start_001"; +} + +/** + * @tc.name: FsWatcherTest_Start_002 + * @tc.desc: Test function of FsWatcher::Start interface for FAILURE when watchEntity is nullptr. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Start_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Start_002"; + // Prepare test condition + FsWatcher fsWatcher(nullptr); + // Do testing + auto result = fsWatcher.Start(); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + auto errCode = result.GetError().GetErrNo(); + EXPECT_EQ(errCode, E_INVAL_CODE); + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Start_002"; +} + +/** + * @tc.name: FsWatcherTest_Start_003 + * @tc.desc: Test function of FsWatcher::Start interface for FAILURE when StartNotify fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Start_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Start_003"; + // Prepare test condition + auto watchEntity = CreateUniquePtr(); + FsWatcher fsWatcher(std::move(watchEntity)); + std::shared_ptr info = std::make_shared(nullptr); + fsWatcher.GetWatchEntity()->data_ = info; + // Prepare test condition for FsFileWatcher + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = -1; // Invalid notifyFd + // Do testing + auto result = fsWatcher.Start(); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + auto errCode = result.GetError().GetErrNo(); + EXPECT_EQ(errCode, E_IO_CODE); + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Start_003"; +} + +/** + * @tc.name: FsWatcherTest_Stop_001 + * @tc.desc: Test function of FsWatcher::Stop interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Stop_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Stop_001"; + // Prepare test condition + auto watchEntity = CreateUniquePtr(); + FsWatcher fsWatcher(std::move(watchEntity)); + std::shared_ptr info = std::make_shared(nullptr); + fsWatcher.GetWatchEntity()->data_ = info; + // Prepare test condition for FsFileWatcher + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_rm_watch(testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(0, 0)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(2).WillRepeatedly(testing::Return(0)); + // Do testing + auto result = fsWatcher.Stop(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_TRUE(result.IsSuccess()); + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Stop_001"; +} + +/** + * @tc.name: FsWatcherTest_Stop_002 + * @tc.desc: Test function of FsWatcher::Stop interface for FAILURE when watchEntity is nullptr. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Stop_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Stop_002"; + // Prepare test condition + FsWatcher fsWatcher(nullptr); + // Do testing + auto result = fsWatcher.Stop(); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + auto errCode = result.GetError().GetErrNo(); + EXPECT_EQ(errCode, E_INVAL_CODE); + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Stop_002"; +} + +/** + * @tc.name: FsWatcherTest_Stop_003 + * @tc.desc: Test function of FsWatcher::Stop interface for FAILURE when StopNotify fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsWatcherMockTest, FsWatcherTest_Stop_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsWatcherMockTest-begin FsWatcherTest_Stop_003"; + // Prepare test condition + auto watchEntity = CreateUniquePtr(); + FsWatcher fsWatcher(std::move(watchEntity)); + std::shared_ptr info = std::make_shared(nullptr); + fsWatcher.GetWatchEntity()->data_ = info; + // Prepare test condition for FsFileWatcher + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = -1; // Invalid notifyFd + // Do testing + auto result = fsWatcher.Stop(); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + auto errCode = result.GetError().GetErrNo(); + EXPECT_EQ(errCode, E_IO_CODE); + GTEST_LOG_(INFO) << "FsWatcherMockTest-end FsWatcherTest_Stop_003"; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp b/interfaces/test/unittest/js/mod_fs/common/fs_err_code.h similarity index 71% rename from interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp rename to interfaces/test/unittest/js/mod_fs/common/fs_err_code.h index 26696c869..7e8a4cbbd 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.cpp +++ b/interfaces/test/unittest/js/mod_fs/common/fs_err_code.h @@ -13,29 +13,22 @@ * limitations under the License. */ -#include "inotify_mock.h" +#ifndef INTERFACES_TEST_UNITTEST_JS_MOD_FS_COMMON_FS_ERR_CODE_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_COMMON_FS_ERR_CODE_H namespace OHOS { namespace FileManagement { namespace ModuleFileIO { namespace Test { -InotifyMock &GetInotifyMock() -{ - return InotifyMock::GetMock(); -} +enum FsErrCode { + E_IO_CODE = 13900005, + E_INVAL_CODE = 13900020, +}; } // namespace Test } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS -extern "C" { -using namespace OHOS::FileManagement::ModuleFileIO::Test; - -int inotify_add_watch(int fd, const char *pathname, uint32_t mask) -{ - return GetInotifyMock().inotify_add_watch(fd, pathname, mask); -} - -} // extern "C" +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_COMMON_FS_ERR_CODE_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.cpp b/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.cpp new file mode 100644 index 000000000..3406f521c --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.cpp @@ -0,0 +1,51 @@ +/* + * 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 "eventfd_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr EventfdMock::eventfdMock = nullptr; + +std::shared_ptr EventfdMock::GetMock() +{ + if (eventfdMock == nullptr) { + eventfdMock = std::make_shared(); + } + return eventfdMock; +} + +void EventfdMock::DestroyMock() +{ + eventfdMock = nullptr; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int eventfd(unsigned int count, int flags) +{ + return EventfdMock::GetMock()->eventfd(count, flags); +} + +} // extern "C" \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.h b/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.h new file mode 100644 index 000000000..e1bbd820d --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.h @@ -0,0 +1,50 @@ +/* + * 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 INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_EVENTFD_MOCK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_EVENTFD_MOCK_H + +#include +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class IEventfdMock { +public: + virtual ~IEventfdMock() = default; + virtual int eventfd(unsigned int, int) = 0; +}; + +class EventfdMock : public IEventfdMock { +public: + MOCK_METHOD(int, eventfd, (unsigned int, int), (override)); + +public: + static std::shared_ptr GetMock(); + static void DestroyMock(); + +private: + static thread_local std::shared_ptr eventfdMock; +}; + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_EVENTFD_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.cpp b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.cpp new file mode 100644 index 000000000..6c4deb01a --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.cpp @@ -0,0 +1,61 @@ +/* + * 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 "inotify_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr InotifyMock::inotifyMock = nullptr; + +std::shared_ptr InotifyMock::GetMock() +{ + if (inotifyMock == nullptr) { + inotifyMock = std::make_shared(); + } + return inotifyMock; +} + +void InotifyMock::DestroyMock() +{ + inotifyMock = nullptr; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int inotify_init() +{ + return InotifyMock::GetMock()->inotify_init(); +} + +int inotify_add_watch(int fd, const char *pathname, uint32_t mask) +{ + return InotifyMock::GetMock()->inotify_add_watch(fd, pathname, mask); +} + +int inotify_rm_watch(int fd, int wd) +{ + return InotifyMock::GetMock()->inotify_rm_watch(fd, wd); +} + +} // extern "C" \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.h similarity index 78% rename from interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h rename to interfaces/test/unittest/js/mod_fs/mock/inotify_mock.h index 3605671c1..188f63a28 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/inotify_mock.h +++ b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.h @@ -27,25 +27,28 @@ namespace Test { class IInotifyMock { public: virtual ~IInotifyMock() = default; + virtual int inotify_init() = 0; virtual int inotify_add_watch(int, const char *, uint32_t) = 0; + virtual int inotify_rm_watch(int, int) = 0; }; class InotifyMock : public IInotifyMock { public: + MOCK_METHOD(int, inotify_init, (), (override)); MOCK_METHOD(int, inotify_add_watch, (int, const char *, uint32_t), (override)); + MOCK_METHOD(int, inotify_rm_watch, (int, int), (override)); - static InotifyMock &GetMock() - { - static InotifyMock mock; - return mock; - } -}; +public: + static std::shared_ptr GetMock(); + static void DestroyMock(); -InotifyMock &GetInotifyMock(); +private: + static thread_local std::shared_ptr inotifyMock; +}; } // namespace Test } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_INOTIFY_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/mock_watcher_callback.h b/interfaces/test/unittest/js/mod_fs/mock/mock_watcher_callback.h new file mode 100644 index 000000000..c1004d84f --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/mock_watcher_callback.h @@ -0,0 +1,41 @@ +/* + * 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 INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_MOCK_WATCHER_CALLBACK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_MOCK_WATCHER_CALLBACK_H + +#include +#include +#include "i_watcher_callback.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +class MockWatcherCallback : public IWatcherCallback { +public: + MOCK_METHOD(bool, IsStrictEquals, (const std::shared_ptr &other), (const, override)); + MOCK_METHOD( + void, InvokeCallback, (const std::string &fileName, uint32_t event, uint32_t cookie), (const, override)); + MOCK_METHOD(std::string, GetClassName, (), (const, override)); +}; + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_MOCK_WATCHER_CALLBACK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/poll_mock.cpp b/interfaces/test/unittest/js/mod_fs/mock/poll_mock.cpp new file mode 100644 index 000000000..fa66cf055 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/poll_mock.cpp @@ -0,0 +1,51 @@ +/* + * 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 "poll_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr PollMock::pollMock = nullptr; + +std::shared_ptr PollMock::GetMock() +{ + if (pollMock == nullptr) { + pollMock = std::make_shared(); + } + return pollMock; +} + +void PollMock::DestroyMock() +{ + pollMock = nullptr; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int poll(struct pollfd *fds, nfds_t n, int timeout) +{ + return PollMock::GetMock()->poll(fds, n, timeout); +} + +} // extern "C" \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/poll_mock.h b/interfaces/test/unittest/js/mod_fs/mock/poll_mock.h new file mode 100644 index 000000000..0dd005710 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/poll_mock.h @@ -0,0 +1,50 @@ +/* + * 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 INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_POLL_MOCK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_POLL_MOCK_H + +#include +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class IPollMock { +public: + virtual ~IPollMock() = default; + virtual int poll(struct pollfd *, nfds_t, int) = 0; +}; + +class PollMock : public IPollMock { +public: + MOCK_METHOD(int, poll, (struct pollfd *, nfds_t, int), (override)); + +public: + static std::shared_ptr GetMock(); + static void DestroyMock(); + +private: + static thread_local std::shared_ptr pollMock; +}; + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_POLL_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.cpp b/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.cpp new file mode 100644 index 000000000..bb646967b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.cpp @@ -0,0 +1,61 @@ +/* + * 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 "unistd_mock.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr UnistdMock::unistdMock = nullptr; + +std::shared_ptr UnistdMock::GetMock() +{ + if (unistdMock == nullptr) { + unistdMock = std::make_shared(); + } + return unistdMock; +} + +void UnistdMock::DestroyMock() +{ + unistdMock = nullptr; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int access(const char *filename, int amode) +{ + return UnistdMock::GetMock()->access(filename, amode); +} + +int close(int fd) +{ + return UnistdMock::GetMock()->close(fd); +} + +ssize_t read(int fd, void *buf, size_t count) +{ + return UnistdMock::GetMock()->read(fd, buf, count); +} + +} // extern "C" \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.h b/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.h new file mode 100644 index 000000000..37dc6d5cf --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.h @@ -0,0 +1,54 @@ +/* + * 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 INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_UNISTD_MOCK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_UNISTD_MOCK_H + +#include +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class IUnistdMock { +public: + virtual ~IUnistdMock() = default; + virtual int access(const char *, int) = 0; + virtual int close(int) = 0; + virtual ssize_t read(int, void *, size_t) = 0; +}; + +class UnistdMock : public IUnistdMock { +public: + MOCK_METHOD(int, access, (const char *, int), (override)); + MOCK_METHOD(int, close, (int), (override)); + MOCK_METHOD(ssize_t, read, (int, void *, size_t), (override)); + +public: + static std::shared_ptr GetMock(); + static void DestroyMock(); + +private: + static thread_local std::shared_ptr unistdMock; +}; + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_UNISTD_MOCK_H diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp index 9f914b2af..2580d8791 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -22,6 +22,7 @@ #include "copy_core.h" #include "inotify_mock.h" #include "mock/uv_fs_mock.h" +#include "unistd_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; @@ -30,6 +31,8 @@ using namespace std; class CopyCoreMockTest : public testing::Test { public: + static constexpr mode_t permission0755 = 0755; + static constexpr mode_t permission0644 = 0644; static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); @@ -52,10 +55,10 @@ const string CopyCoreMockTest::destFile = destDir + "/dest.txt"; void CopyCoreMockTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; - mkdir(testDir.c_str(), 0755); - mkdir(srcDir.c_str(), 0755); - mkdir(destDir.c_str(), 0755); - int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, 0644); + mkdir(testDir.c_str(), permission0755); + mkdir(srcDir.c_str(), permission0755); + mkdir(destDir.c_str(), permission0755); + int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } @@ -74,6 +77,8 @@ void CopyCoreMockTest::TearDownTestCase(void) rmdir(testDir.c_str()); Uvfs::ins = nullptr; uvMock = nullptr; + UnistdMock::DestroyMock(); + InotifyMock::DestroyMock(); } void CopyCoreMockTest::SetUp(void) @@ -84,7 +89,6 @@ void CopyCoreMockTest::SetUp(void) void CopyCoreMockTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; - remove(destFile.c_str()); } /** @@ -102,7 +106,9 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopyFile_001, testing::ext::TestSize infos->isFile = true; infos->srcPath = CopyCoreMockTest::srcFile; infos->destPath = CopyCoreMockTest::destFile; + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); EXPECT_CALL(*uvMock, uv_fs_sendfile(_, _, _, _, _, _, _)).WillOnce(Return(-1)); auto res = CopyCore::CopyFile(srcFile, destFile, infos); @@ -125,12 +131,16 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_DoCopy_001, testing::ext::TestSize.L string srcUri = "file://" + srcFile; string destUri = "file://" + destFile; optional options; + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); EXPECT_CALL(*uvMock, uv_fs_sendfile(_, _, _, _, _, _, _)).WillOnce(Return(0)); auto res = CopyCore::DoCopy(srcUri, destUri, options); EXPECT_EQ(res.IsSuccess(), true); EXPECT_TRUE(filesystem::exists(destFile)); + int ret = remove(destFile.c_str()); + EXPECT_TRUE(ret == 0); GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_DoCopy_001"; } @@ -147,26 +157,27 @@ HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_001, testing::ext::TestSi GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_CopySubDir_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), 0755); + mkdir(subDir.c_str(), permission0755); string subFile = subDir + "/sub_file.txt"; - int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } close(fd); - testing::StrictMock &inotifyMock = static_cast &>(GetInotifyMock()); + auto inotifyMock = InotifyMock::GetMock(); string destSubDir = destDir + "/sub_dir"; auto infos = make_shared(); infos->notifyFd = 1; - EXPECT_CALL(inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) - .Times(1) - .WillOnce(testing::Return(0)); + auto unistdMock = UnistdMock::GetMock(); + + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)).WillOnce(testing::Return(0)); auto res = CopyCore::CopySubDir(subDir, destSubDir, infos); - testing::Mock::VerifyAndClearExpectations(&inotifyMock); EXPECT_EQ(res, UNKNOWN_ERR); - remove(subFile.c_str()); + int ret = remove(subFile.c_str()); + EXPECT_TRUE(ret == 0); rmdir(subDir.c_str()); rmdir(destSubDir.c_str()); GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_CopySubDir_001"; diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp index ed452c1d0..afcc82a8a 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -24,10 +24,10 @@ using namespace testing; using namespace testing::ext; using namespace std; -const int g_permissions = 0755; - class CopyCoreTest : public testing::Test { public: + static constexpr mode_t permission0755 = 0755; //rwxr-xr-x + static constexpr mode_t permission0644 = 0644; //rw-r--r-- static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); @@ -49,10 +49,10 @@ const string CopyCoreTest::destFile = destDir + "/dest.txt"; void CopyCoreTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; - mkdir(testDir.c_str(), g_permissions); - mkdir(srcDir.c_str(), g_permissions); - mkdir(destDir.c_str(), g_permissions); - int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, 0644); + mkdir(testDir.c_str(), permission0755); + mkdir(srcDir.c_str(), permission0755); + mkdir(destDir.c_str(), permission0755); + int32_t fd = open(srcFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } @@ -453,9 +453,9 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_001, testing::ext::TestSize.Level GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopySubDir_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), g_permissions); + mkdir(subDir.c_str(), permission0755); string subFile = subDir + "/sub_file.txt"; - int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } @@ -488,9 +488,9 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopySubDir_002, testing::ext::TestSize.Level GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopySubDir_002"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), g_permissions); + mkdir(subDir.c_str(), permission0755); string subFile = subDir + "/sub_file.txt"; - int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } @@ -520,9 +520,9 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_RecurCopyDir_001, testing::ext::TestSize.Lev GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_RecurCopyDir_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), g_permissions); + mkdir(subDir.c_str(), permission0755); string subFile = subDir + "/sub_file.txt"; - int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } @@ -555,9 +555,9 @@ HWTEST_F(CopyCoreTest, CopyCoreTest_CopyDirFunc_001, testing::ext::TestSize.Leve GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_CopyDirFunc_001"; string subDir = srcDir + "/sub_dir"; - mkdir(subDir.c_str(), g_permissions); + mkdir(subDir.c_str(), permission0755); string subFile = subDir + "/sub_file.txt"; - int fd = open(subFile.c_str(), O_CREAT | O_RDWR, 0644); + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); if (fd < 0) { EXPECT_TRUE(false); } diff --git a/interfaces/test/unittest/js/mod_fs/properties/open_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/open_core_mock_test.cpp index 33f25f3cd..9463f6399 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/open_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/open_core_mock_test.cpp @@ -13,14 +13,15 @@ * limitations under the License. */ -#include "mock/uv_fs_mock.h" -#include "open_core.h" - #include #include #include #include +#include "mock/uv_fs_mock.h" +#include "open_core.h" +#include "unistd_mock.h" + namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; using namespace testing::ext; @@ -32,6 +33,8 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); + +private: static inline shared_ptr uvMock = nullptr; }; @@ -47,6 +50,7 @@ void OpenCoreMockTest::TearDownTestCase(void) GTEST_LOG_(INFO) << "TearDownTestCase"; Uvfs::ins = nullptr; uvMock = nullptr; + UnistdMock::DestroyMock(); } void OpenCoreMockTest::SetUp(void) @@ -70,9 +74,9 @@ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_001, testing::ext::TestSize.L { GTEST_LOG_(INFO) << "OpenCoreMockTest-begin OpenCoreMockTest_DoOpen_001"; - string path = "/test/open_test.txt"; + string path = "/test/OpenCoreMockTest_DoOpen_001"; int32_t mode = 0; - + EXPECT_CALL(*uvMock, uv_fs_open(_, _, _, _, _, _)).WillOnce(Return(0)); auto res = OpenCore::DoOpen(path, mode); EXPECT_EQ(res.IsSuccess(), true); @@ -91,11 +95,15 @@ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_002, testing::ext::TestSize.L { GTEST_LOG_(INFO) << "OpenCoreMockTest-begin OpenCoreMockTest_DoOpen_002"; - string path = "file://test/open_test.txt"; + string path = "file://test/OpenCoreMockTest_DoOpen_002"; int32_t mode = 0; + auto unistdMock = UnistdMock::GetMock(); EXPECT_CALL(*uvMock, uv_fs_open(_, _, _, _, _, _)).WillOnce(Return(0)); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).WillRepeatedly(testing::Return(0)); auto res = OpenCore::DoOpen(path, mode); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); EXPECT_EQ(res.IsSuccess(), true); GTEST_LOG_(INFO) << "OpenCoreMockTest-end OpenCoreMockTest_DoOpen_002"; @@ -112,11 +120,15 @@ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_003, testing::ext::TestSize.L { GTEST_LOG_(INFO) << "OpenCoreMockTest-begin OpenCoreMockTest_DoOpen_003"; - string path = "file://test/open_test.txt"; + string path = "file://test/OpenCoreMockTest_DoOpen_003"; int32_t mode = 0; + auto unistdMock = UnistdMock::GetMock(); EXPECT_CALL(*uvMock, uv_fs_open(_, _, _, _, _, _)).WillOnce(Return(-1)); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(*unistdMock, access(testing::_, testing::_)).WillRepeatedly(testing::Return(0)); auto res = OpenCore::DoOpen(path, mode); + testing::Mock::VerifyAndClearExpectations(&unistdMock); EXPECT_EQ(res.IsSuccess(), false); GTEST_LOG_(INFO) << "OpenCoreMockTest-end OpenCoreMockTest_DoOpen_003"; @@ -133,7 +145,7 @@ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_004, testing::ext::TestSize.L { GTEST_LOG_(INFO) << "OpenCoreMockTest-begin OpenCoreMockTest_DoOpen_004"; - string path = "/test/open_test.txt"; + string path = "/test/OpenCoreMockTest_DoOpen_004"; int32_t mode = 0; EXPECT_CALL(*uvMock, uv_fs_open(_, _, _, _, _, _)).WillOnce(Return(-1)); diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp index 287d5196f..808520785 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp @@ -20,6 +20,7 @@ #include #include "copy_core.h" +#include "unistd_mock.h" using namespace OHOS; using namespace OHOS::Storage::DistributedFile; @@ -153,6 +154,7 @@ void TransListenerCoreMockTest::SetUpTestCase(void) void TransListenerCoreMockTest::TearDownTestCase(void) { rmdir(g_path.c_str()); + UnistdMock::DestroyMock(); GTEST_LOG_(INFO) << "TearDownTestCase"; } @@ -183,7 +185,9 @@ HWTEST_F(TransListenerCoreMockTest, TransListenerCoreMockTest_PrepareCopySession string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; string disSandboxPath = "disSandboxPath"; + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); EXPECT_CALL(GetMock(), PrepareSession(testing::_, testing::_, testing::_, testing::_, testing::_)) .WillOnce(testing::Return(ERRNO_NOERR)); auto result = TransListenerCore::PrepareCopySession(srcUri, "destUri", nullptr, info, disSandboxPath); @@ -207,9 +211,11 @@ HWTEST_F(TransListenerCoreMockTest, TransListenerCoreMockTest_CopyFileFromSoftBu info.authority = FILE_MANAGER_AUTHORITY; string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; - shared_ptr transListener(new TransListenerCore); - std::shared_ptr infos(new FsFileInfos); + std::shared_ptr transListener = std::make_shared(); + std::shared_ptr infos = std::make_shared(); + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); EXPECT_CALL(GetMock(), PrepareSession(testing::_, testing::_, testing::_, testing::_, testing::_)) .WillOnce(testing::Return(ERRNO_NOERR)); diff --git a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp index ff568f5fd..5e6dca235 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp @@ -565,7 +565,7 @@ HWTEST_F(TransListenerCoreTest, TransListenerCoreTest_CopyFileFromSoftBus_001, t string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; std::shared_ptr transListener = std::make_shared(); - std::shared_ptr infos(new FsFileInfos); + std::shared_ptr infos = std::make_shared(); transListener->copyEvent_.copyResult = FAILED; auto res = transListener->CopyFileFromSoftBus(srcUri, "destUri", infos, nullptr); diff --git a/interfaces/test/unittest/js/mod_fs/properties/watcher_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/watcher_core_mock_test.cpp new file mode 100644 index 000000000..322bca06b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/watcher_core_mock_test.cpp @@ -0,0 +1,225 @@ +/* + * 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 "eventfd_mock.h" +#include "filemgmt_libhilog.h" +#include "fs_file_watcher.h" +#include "inotify_mock.h" +#include "mock_watcher_callback.h" +#include "watcher_core.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +class WatcherCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void WatcherCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void WatcherCoreMockTest::TearDownTestCase(void) +{ + EventfdMock::DestroyMock(); + InotifyMock::DestroyMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void WatcherCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + errno = 0; // Reset errno +} + +void WatcherCoreMockTest::TearDown(void) +{ + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.taskRunning_ = false; + watcher.run_ = false; + watcher.reading_ = false; + watcher.closed_ = false; + watcher.notifyFd_ = -1; + watcher.eventFd_ = -1; + watcher.dataCache_.ClearCache(); + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: WatcherCoreMockTest_DoCreateWatcher_001 + * @tc.desc: Test function of WatcherCore::DoCreateWatcher interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(WatcherCoreMockTest, WatcherCoreMockTest_DoCreateWatcher_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "WatcherCoreMockTest-begin WatcherCoreMockTest_DoCreateWatcher_001"; + // Prepare test parameters + std::string path = "/test/WatcherCoreMockTest_DoCreateWatcher_001"; + int32_t events = IN_CREATE; + std::shared_ptr callback = std::make_shared(); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + auto eventfdMock = EventfdMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::Return(1)); + EXPECT_CALL(*eventfdMock, eventfd(testing::_, testing::_)).Times(1).WillOnce(testing::Return(2)); + // Do testing + auto result = WatcherCore::DoCreateWatcher(path, events, callback); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + testing::Mock::VerifyAndClearExpectations(eventfdMock.get()); + EXPECT_TRUE(result.IsSuccess()); + GTEST_LOG_(INFO) << "WatcherCoreMockTest-end WatcherCoreMockTest_DoCreateWatcher_001"; +} + +/** + * @tc.name: WatcherCoreMockTest_DoCreateWatcher_002 + * @tc.desc: Test function of WatcherCore::DoCreateWatcher interface for FAILURE when InitNotify fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherCoreMockTest, WatcherCoreMockTest_DoCreateWatcher_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherCoreMockTest-begin WatcherCoreMockTest_DoCreateWatcher_002"; + // Prepare test parameters + std::string path = "/test/WatcherCoreMockTest_DoCreateWatcher_002"; + int32_t events = IN_CREATE; + std::shared_ptr callback = std::make_shared(); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + auto result = WatcherCore::DoCreateWatcher(path, events, callback); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_FALSE(result.IsSuccess()); + GTEST_LOG_(INFO) << "WatcherCoreMockTest-end WatcherCoreMockTest_DoCreateWatcher_002"; +} + +/** + * @tc.name: WatcherCoreMockTest_DoCreateWatcher_003 + * @tc.desc: Test function of WatcherCore::DoCreateWatcher interface for FAILURE when events are invalid. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherCoreMockTest, WatcherCoreMockTest_DoCreateWatcher_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherCoreMockTest-begin WatcherCoreMockTest_DoCreateWatcher_003"; + // Prepare test parameters + std::string path = "/test/WatcherCoreMockTest_DoCreateWatcher_003"; + int32_t events = -1; + std::shared_ptr callback = std::make_shared(); + // Do testing + auto result = WatcherCore::DoCreateWatcher(path, events, callback); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + GTEST_LOG_(INFO) << "WatcherCoreMockTest-end WatcherCoreMockTest_DoCreateWatcher_003"; +} + +/** + * @tc.name: WatcherCoreMockTest_DoCreateWatcher_004 + * @tc.desc: Test function of WatcherCore::DoCreateWatcher interface for FAILURE when CheckEventValid false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherCoreMockTest, WatcherCoreMockTest_DoCreateWatcher_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherCoreMockTest-begin WatcherCoreMockTest_DoCreateWatcher_004"; + // Prepare test parameters + std::string path = "/test/WatcherCoreMockTest_DoCreateWatcher_004"; + int32_t invalidEvents = ~IN_ALL_EVENTS; + std::shared_ptr callback = std::make_shared(); + // Do testing + auto result = WatcherCore::DoCreateWatcher(path, invalidEvents, callback); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + GTEST_LOG_(INFO) << "WatcherCoreMockTest-end WatcherCoreMockTest_DoCreateWatcher_004"; +} + +/** + * @tc.name: WatcherCoreMockTest_DoCreateWatcher_005 + * @tc.desc: Test function of WatcherCore::DoCreateWatcher interface for FAILURE when callback is null. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherCoreMockTest, WatcherCoreMockTest_DoCreateWatcher_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherCoreMockTest-begin WatcherCoreMockTest_DoCreateWatcher_005"; + // Prepare test parameters + std::string path = "/test/WatcherCoreMockTest_DoCreateWatcher_005"; + int32_t events = IN_CREATE; + std::shared_ptr callback = nullptr; + // Do testing + auto result = WatcherCore::DoCreateWatcher(path, events, callback); + // Verify results + EXPECT_FALSE(result.IsSuccess()); + GTEST_LOG_(INFO) << "WatcherCoreMockTest-end WatcherCoreMockTest_DoCreateWatcher_005"; +} + +/** + * @tc.name: WatcherCoreMockTest_DoCreateWatcher_006 + * @tc.desc: Test function of WatcherCore::DoCreateWatcher interface for FAILURE when AddWatcherInfo fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherCoreMockTest, WatcherCoreMockTest_DoCreateWatcher_006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherCoreMockTest-begin WatcherCoreMockTest_DoCreateWatcher_006"; + // Prepare test parameters + std::string path = "/test/WatcherCoreMockTest_DoCreateWatcher_006"; + int32_t events = IN_CREATE; + std::shared_ptr callback = std::make_shared(); + // Prepare test condition + int32_t expectedWd = 100; + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; // Valid notifyFd + auto info = std::make_shared(callback); + info->fileName = "/test/WatcherCoreMockTest_DoCreateWatcher_006"; + info->events = IN_CREATE; + info->wd = expectedWd; + watcher.dataCache_.AddWatcherInfo(info); + // Set mock behaviors + auto cbMock = std::dynamic_pointer_cast(callback); + EXPECT_CALL(*cbMock, IsStrictEquals(testing::_)).Times(1).WillOnce(testing::Return(true)); + // Do testing + auto result = WatcherCore::DoCreateWatcher(path, events, callback); + // Verify results + testing::Mock::VerifyAndClearExpectations(cbMock.get()); + EXPECT_FALSE(result.IsSuccess()); + GTEST_LOG_(INFO) << "WatcherCoreMockTest-end WatcherCoreMockTest_DoCreateWatcher_006"; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file -- Gitee