diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index f9fd98aa6b690e06584f6c0c461b485cf610796f..d2423e40cb0c5a85cc97e5c977e848909bacfc0e 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -628,14 +628,17 @@ group("build_kits_js") { group("ani_file_api") { deps = [ + ":ani_file_environment", ":ani_file_fs", ":ani_file_hash", ":ani_file_securitylabel", + ":ani_file_statvfs", ] } config("ani_config") { include_dirs = [ + "./include", "${file_api_path}/interfaces/kits/rust/include", "${utils_path}/common/include", "${utils_path}/filemgmt_libfs/include", @@ -661,13 +664,28 @@ config("ani_config") { ohos_shared_library("ani_file_fs") { public_configs = [ ":ani_config" ] include_dirs = [ + "include/ipc", "src/mod_fs/ani", + "src/mod_fs/class_atomicfile", + "src/mod_fs/class_atomicfile/ani", "src/mod_fs/class_file", "src/mod_fs/class_file/ani", + "src/mod_fs/class_randomaccessfile", + "src/mod_fs/class_randomaccessfile/ani", + "src/mod_fs/class_readeriterator", + "src/mod_fs/class_readeriterator/ani", "src/mod_fs/class_stat", "src/mod_fs/class_stat/ani", + "src/mod_fs/class_stream", + "src/mod_fs/class_stream/ani", + "src/mod_fs/class_tasksignal", + "src/mod_fs/class_tasksignal/ani", + "src/mod_fs/class_watcher", + "src/mod_fs/class_watcher/ani", "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", @@ -675,42 +693,107 @@ ohos_shared_library("ani_file_fs") { "src/common/ani_helper/type_converter.cpp", "src/common/file_helper/fd_guard.cpp", "src/mod_fs/ani/bind_function_class.cpp", + "src/mod_fs/class_atomicfile/ani/atomicfile_ani.cpp", + "src/mod_fs/class_atomicfile/fs_atomicfile.cpp", "src/mod_fs/class_file/ani/file_ani.cpp", "src/mod_fs/class_file/ani/file_wrapper.cpp", "src/mod_fs/class_file/file_instantiator.cpp", "src/mod_fs/class_file/fs_file.cpp", + "src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp", + "src/mod_fs/class_randomaccessfile/fs_randomaccessfile.cpp", + "src/mod_fs/class_readeriterator/ani/reader_iterator_ani.cpp", + "src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.cpp", + "src/mod_fs/class_readeriterator/fs_reader_iterator.cpp", + "src/mod_fs/class_stat/ani/lstat_ani.cpp", "src/mod_fs/class_stat/ani/stat_ani.cpp", "src/mod_fs/class_stat/ani/stat_wrapper.cpp", "src/mod_fs/class_stat/fs_stat.cpp", "src/mod_fs/class_stat/stat_instantiator.cpp", + "src/mod_fs/class_stream/ani/stream_ani.cpp", + "src/mod_fs/class_stream/ani/stream_wrapper.cpp", + "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/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", + "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", "src/mod_fs/properties/ani/close_ani.cpp", + "src/mod_fs/properties/ani/connectdfs_ani.cpp", + "src/mod_fs/properties/ani/copy_ani.cpp", + "src/mod_fs/properties/ani/copy_dir_ani.cpp", "src/mod_fs/properties/ani/copy_file_ani.cpp", + "src/mod_fs/properties/ani/create_randomaccessfile_ani.cpp", + "src/mod_fs/properties/ani/create_stream_ani.cpp", + "src/mod_fs/properties/ani/disconnectdfs_ani.cpp", + "src/mod_fs/properties/ani/dup_ani.cpp", + "src/mod_fs/properties/ani/fdatasync_ani.cpp", + "src/mod_fs/properties/ani/fdopen_stream_ani.cpp", + "src/mod_fs/properties/ani/fsync_ani.cpp", "src/mod_fs/properties/ani/listfile_ani.cpp", + "src/mod_fs/properties/ani/lseek_ani.cpp", "src/mod_fs/properties/ani/mkdir_ani.cpp", + "src/mod_fs/properties/ani/mkdtemp_ani.cpp", "src/mod_fs/properties/ani/move_ani.cpp", + "src/mod_fs/properties/ani/movedir_ani.cpp", "src/mod_fs/properties/ani/open_ani.cpp", "src/mod_fs/properties/ani/read_ani.cpp", + "src/mod_fs/properties/ani/read_lines_ani.cpp", "src/mod_fs/properties/ani/read_text_ani.cpp", + "src/mod_fs/properties/ani/rename_ani.cpp", "src/mod_fs/properties/ani/rmdir_ani.cpp", + "src/mod_fs/properties/ani/symlink_ani.cpp", "src/mod_fs/properties/ani/truncate_ani.cpp", "src/mod_fs/properties/ani/unlink_ani.cpp", + "src/mod_fs/properties/ani/utimes_ani.cpp", + "src/mod_fs/properties/ani/watcher_ani.cpp", "src/mod_fs/properties/ani/write_ani.cpp", + "src/mod_fs/properties/ani/xattr_ani.cpp", "src/mod_fs/properties/close_core.cpp", + "src/mod_fs/properties/connectdfs_core.cpp", + "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", + "src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.cpp", + "src/mod_fs/properties/disconnectdfs_core.cpp", + "src/mod_fs/properties/dup_core.cpp", + "src/mod_fs/properties/fdatasync_core.cpp", + "src/mod_fs/properties/fdopen_stream_core.cpp", + "src/mod_fs/properties/fsync_core.cpp", "src/mod_fs/properties/listfile_core.cpp", + "src/mod_fs/properties/lseek_core.cpp", + "src/mod_fs/properties/lstat_core.cpp", "src/mod_fs/properties/mkdir_core.cpp", + "src/mod_fs/properties/mkdtemp_core.cpp", "src/mod_fs/properties/move_core.cpp", + "src/mod_fs/properties/movedir_core.cpp", "src/mod_fs/properties/open_core.cpp", "src/mod_fs/properties/read_core.cpp", + "src/mod_fs/properties/read_lines_core.cpp", "src/mod_fs/properties/read_text_core.cpp", + "src/mod_fs/properties/rename_core.cpp", "src/mod_fs/properties/rmdir_core.cpp", "src/mod_fs/properties/stat_core.cpp", + "src/mod_fs/properties/symlink_core.cpp", "src/mod_fs/properties/truncate_core.cpp", "src/mod_fs/properties/unlink_core.cpp", + "src/mod_fs/properties/utimes_core.cpp", + "src/mod_fs/properties/watcher_core.cpp", "src/mod_fs/properties/write_core.cpp", + "src/mod_fs/properties/xattr_core.cpp", ] deps = [ ":ohos_file_fs_abc_etc", @@ -724,7 +807,7 @@ ohos_shared_library("ani_file_fs") { external_deps = [ "ability_runtime:ability_manager", "app_file_service:fileuri_native", - "bounds_checking_function:libsec_static", + "bounds_checking_function:libsec_shared", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "c_utils:utils", @@ -777,6 +860,8 @@ ohos_shared_library("ani_file_hash") { include_dirs = [ "src/mod_hash", "src/mod_hash/ani", + "src/mod_hash/class_hashstream", + "src/mod_hash/class_hashstream/ani", ] sources = [ "src/common/ani_helper/ani_signature.cpp", @@ -787,6 +872,8 @@ ohos_shared_library("ani_file_hash") { "src/mod_fs/fs_utils.cpp", "src/mod_hash/ani/bind_function_class.cpp", "src/mod_hash/ani/hash_ani.cpp", + "src/mod_hash/class_hashstream/ani/hashstream_ani.cpp", + "src/mod_hash/class_hashstream/hs_hashstream.cpp", "src/mod_hash/hash_core.cpp", ] @@ -797,10 +884,8 @@ ohos_shared_library("ani_file_hash") { "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", ] external_deps = [ - "bounds_checking_function:libsec_static", - "eventhandler:libeventhandler", + "bounds_checking_function:libsec_shared", "hilog:libhilog", - "ipc:ipc_core", "libuv:uv", "openssl:libcrypto_shared", "runtime_core:ani", @@ -862,10 +947,8 @@ ohos_shared_library("ani_file_securitylabel") { "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", ] external_deps = [ - "bounds_checking_function:libsec_static", - "eventhandler:libeventhandler", + "bounds_checking_function:libsec_shared", "hilog:libhilog", - "ipc:ipc_core", "libuv:uv", "runtime_core:ani", "runtime_core:ani_helpers", @@ -901,3 +984,141 @@ ohos_prebuilt_etc("ohos_file_securityLabel_abc_etc") { part_name = "file_api" deps = [ ":ohos_file_securityLabel_abc" ] } + +ohos_shared_library("ani_file_environment") { + public_configs = [ ":ani_config" ] + include_dirs = [ + "src/mod_environment/ani", + "src/mod_environment", + ] + sources = [ + "src/common/ani_helper/ani_signature.cpp", + "src/common/ani_helper/error_handler.cpp", + "src/common/ani_helper/type_converter.cpp", + "src/common/file_helper/fd_guard.cpp", + "src/mod_environment/ani/bind_function_class.cpp", + "src/mod_environment/ani/environment_ani.cpp", + "src/mod_environment/environment_core.cpp", + "src/mod_fs/fs_utils.cpp", + ] + + deps = [ + ":ohos_file_environment_abc_etc", + "${file_api_path}/interfaces/kits/rust:rust_file", + "${utils_path}/filemgmt_libfs:filemgmt_libfs", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + ] + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", + "bounds_checking_function:libsec_shared", + "hilog:libhilog", + "init:libbegetutil", + "ipc:ipc_core", + "libuv:uv", + "openssl:libcrypto_shared", + "os_account:os_account_innerkits", + "runtime_core:ani", + "runtime_core:ani_helpers", + "runtime_core:libarkruntime", + ] + use_exceptions = true + + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + output_extension = "so" + subsystem_name = "filemanagement" + part_name = "file_api" +} + +generate_static_abc("ohos_file_environment_abc") { + base_url = "./src/mod_environment/ani/ets" + files = [ "./src/mod_environment/ani/ets/@ohos.file.environment.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/ohos_file_environment_abc.abc" +} + +ohos_prebuilt_etc("ohos_file_environment_abc_etc") { + source = "$target_out_dir/ohos_file_environment_abc.abc" + module_install_dir = "framework" + subsystem_name = "filemanagement" + part_name = "file_api" + deps = [ ":ohos_file_environment_abc" ] +} + +ohos_shared_library("ani_file_statvfs") { + public_configs = [ ":ani_config" ] + include_dirs = [ + "src/mod_statvfs/ani", + "src/mod_statvfs", + ] + sources = [ + "src/common/ani_helper/ani_signature.cpp", + "src/common/ani_helper/error_handler.cpp", + "src/common/ani_helper/type_converter.cpp", + "src/common/file_helper/fd_guard.cpp", + "src/mod_fs/fs_utils.cpp", + "src/mod_statvfs/ani/bind_function_class.cpp", + "src/mod_statvfs/ani/statvfs_ani.cpp", + "src/mod_statvfs/statvfs_core.cpp", + ] + + deps = [ + ":ohos_file_statvfs_abc_etc", + "${file_api_path}/interfaces/kits/rust:rust_file", + "${utils_path}/filemgmt_libfs:filemgmt_libfs", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + ] + external_deps = [ + "bounds_checking_function:libsec_shared", + "hilog:libhilog", + "libuv:uv", + "runtime_core:ani", + "runtime_core:ani_helpers", + "runtime_core:libarkruntime", + ] + use_exceptions = true + cflags = [ + "-fdata-sections", + "-ffunction-sections", + "-Oz", + ] + cflags_cc = [ + "-fvisibility-inlines-hidden", + "-Oz", + ] + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + output_extension = "so" + subsystem_name = "filemanagement" + part_name = "file_api" +} + +generate_static_abc("ohos_file_statvfs_abc") { + base_url = "./src/mod_statvfs/ani/ets" + files = [ "./src/mod_statvfs/ani/ets/@ohos.file.statvfs.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/ohos_file_statvfs_abc.abc" +} + +ohos_prebuilt_etc("ohos_file_statvfs_abc_etc") { + source = "$target_out_dir/ohos_file_statvfs_abc.abc" + module_install_dir = "framework" + subsystem_name = "filemanagement" + part_name = "file_api" + deps = [ ":ohos_file_statvfs_abc" ] +} diff --git a/interfaces/kits/js/src/mod_environment/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_environment/ani/bind_function_class.cpp index f335756607cdf8da2bc42590b0473a0dff6645dc..dfda601139d779543f2420a01958bbc6a024dcdd 100644 --- a/interfaces/kits/js/src/mod_environment/ani/bind_function_class.cpp +++ b/interfaces/kits/js/src/mod_environment/ani/bind_function_class.cpp @@ -14,7 +14,6 @@ */ #include - #include "ani_signature.h" #include "bind_function.h" #include "environment_ani.h" diff --git a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp index f8da76c82eceb3b8b1dc01ce8ba6db462bd5668c..ddc7129800da9684bd922d796a61a9580c619cf3 100644 --- a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp +++ b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp @@ -1,43 +1,96 @@ /* - * 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 +* 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 "access_ani.h" #include "ani_signature.h" +#include "atomicfile_ani.h" #include "bind_function.h" #include "close_ani.h" +#include "connectdfs_ani.h" +#include "copy_ani.h" +#include "copy_dir_ani.h" #include "copy_file_ani.h" +#include "create_randomaccessfile_ani.h" +#include "create_stream_ani.h" +#include "disconnectdfs_ani.h" +#include "dup_ani.h" +#include "fdatasync_ani.h" +#include "fdopen_stream_ani.h" #include "file_ani.h" +#include "filemgmt_libhilog.h" +#include "fsync_ani.h" +#include "fs_watcher_ani.h" #include "listfile_ani.h" +#include "lseek_ani.h" +#include "lstat_ani.h" #include "mkdir_ani.h" +#include "mkdtemp_ani.h" #include "move_ani.h" -#include "read_ani.h" -#include "rmdir_ani.h" +#include "movedir_ani.h" #include "open_ani.h" +#include "randomaccessfile_ani.h" +#include "read_ani.h" +#include "read_lines_ani.h" #include "read_text_ani.h" +#include "reader_iterator_ani.h" +#include "rename_ani.h" +#include "rmdir_ani.h" #include "stat_ani.h" +#include "stream_ani.h" +#include "symlink_ani.h" +#include "task_signal_ani.h" #include "truncate_ani.h" #include "unlink_ani.h" +#include "utimes_ani.h" +#include "watcher_ani.h" #include "write_ani.h" +#include "xattr_ani.h" using namespace OHOS::FileManagement::ModuleFileIO::ANI; using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; +static ani_status BindRafFileMethods(ani_env *env) +{ + auto classDesc = FS::RandomAccessFileInner::classDesc.c_str(); + + std::array methods = { + ani_native_function { + "setFilePointer0", nullptr, reinterpret_cast(RandomAccessFileAni::SetFilePointer) }, + ani_native_function { "close", nullptr, reinterpret_cast(RandomAccessFileAni::Close) }, + ani_native_function { "writeSync0", nullptr, reinterpret_cast(RandomAccessFileAni::WriteSync) }, + ani_native_function { "readSync0", nullptr, reinterpret_cast(RandomAccessFileAni::ReadSync) }, + }; + + return BindClass(env, classDesc, methods); +} + +static ani_status BindWatcherClassMethods(ani_env *env) +{ + auto classDesc = FS::WatcherInner::classDesc.c_str(); + + std::array methods = { + ani_native_function { "start", nullptr, reinterpret_cast(FsWatcherAni::Start) }, + ani_native_function { "stop", nullptr, reinterpret_cast(FsWatcherAni::Stop) }, + }; + + return BindClass(env, classDesc, methods); +} + static ani_status BindFileMethods(ani_env *env) { auto classDesc = FS::FileInner::classDesc.c_str(); @@ -52,6 +105,17 @@ static ani_status BindFileMethods(ani_env *env) return BindClass(env, classDesc, methods); } +static ani_status BindReaderIteratorMethods(ani_env *env) +{ + auto classDesc = FS::ReaderIteratorInner::classDesc.c_str(); + + std::array methods = { + ani_native_function { "next", nullptr, reinterpret_cast(ReaderIteratorAni::Next) }, + }; + + return BindClass(env, classDesc, methods); +} + static ani_status BindStatClassMethods(ani_env *env) { auto classDesc = FS::StatInner::classDesc.c_str(); @@ -69,6 +133,49 @@ static ani_status BindStatClassMethods(ani_env *env) return BindClass(env, classDesc, methods); } +static ani_status BindStreamMethods(ani_env *env) +{ + auto classDesc = FS::StreamInner::classDesc.c_str(); + + std::array methods = { + ani_native_function { "closeSync", nullptr, reinterpret_cast(StreamAni::Close) }, + ani_native_function { "flushSync", nullptr, reinterpret_cast(StreamAni::Flush) }, + ani_native_function { "readSync", nullptr, reinterpret_cast(StreamAni::Read) }, + ani_native_function { "writeSync", nullptr, reinterpret_cast(StreamAni::Write) }, + ani_native_function { "seek", nullptr, reinterpret_cast(StreamAni::Seek) }, + }; + + return BindClass(env, classDesc, methods); +} + +static ani_status BindTaskSignalClassMethods(ani_env *env) +{ + auto classDesc = FS::TaskSignal::classDesc.c_str(); + + std::array methods = { + ani_native_function { "cancel", nullptr, reinterpret_cast(TaskSignalAni::Cancel) }, + ani_native_function { "onCancelNative", nullptr, reinterpret_cast(TaskSignalAni::OnCancel) }, + }; + + return BindClass(env, classDesc, methods); +} + +static ani_status BindAtomicFileMethods(ani_env *env) +{ + auto classDesc = FS::AtomicFile::classDesc.c_str(); + auto ctorDesc = FS::AtomicFile::ctorDesc.c_str(); + auto ctorSig = FS::AtomicFile::ctorSig.c_str(); + + std::array methods = { + ani_native_function { "getPath", nullptr, reinterpret_cast(AtomicFileAni::GetPath) }, + ani_native_function { "getBaseFile", nullptr, reinterpret_cast(AtomicFileAni::GetBaseFile) }, + ani_native_function { "readFully", nullptr, reinterpret_cast(AtomicFileAni::ReadFully) }, + ani_native_function { "delete", nullptr, reinterpret_cast(AtomicFileAni::Delete) }, + ani_native_function { ctorDesc, ctorSig, reinterpret_cast(AtomicFileAni::Constructor) }, + }; + + return BindClass(env, classDesc, methods); +} const static string mkdirCtorSig0 = Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType }); const static string mkdirCtorSig1 = Builder::BuildSignatureDescriptor({ BuiltInTypes::stringType, BasicTypes::booleanType }); @@ -79,19 +186,43 @@ static ani_status BindStaticMethods(ani_env *env) std::array methods = { ani_native_function { "closeSync", nullptr, reinterpret_cast(CloseAni::CloseSync) }, + ani_native_function { "connectDfs", nullptr, reinterpret_cast(ConnectDfsAni::ConnectDfsSync) }, + ani_native_function { "copyDirSync", nullptr, reinterpret_cast(CopyDirAni::CopyDirSync) }, ani_native_function { "copyFileSync", nullptr, reinterpret_cast(CopyFileAni::CopyFileSync) }, + ani_native_function { "copySync", nullptr, reinterpret_cast(CopyAni::CopySync) }, + ani_native_function { "createRandomAccessFileSync", nullptr, + reinterpret_cast(CreateRandomAccessFileAni::CreateRandomAccessFileSync) }, + ani_native_function { + "createStreamSync", nullptr, reinterpret_cast(CreateStreamAni::CreateStreamSync) }, + ani_native_function { "createWatcherSync", nullptr, reinterpret_cast(WatcherAni::CreateWatcherSync) }, + ani_native_function { "disConnectDfs", nullptr, reinterpret_cast(DisConnectDfsAni::DisConnectDfsSync) }, ani_native_function { "doAccessSync", nullptr, reinterpret_cast(AccessAni::AccessSync3) }, + ani_native_function { "dup", nullptr, reinterpret_cast(DupAni::Dup) }, + ani_native_function { "fdatasyncSync", nullptr, reinterpret_cast(FDataSyncAni::FDataSyncSync) }, + ani_native_function { + "fdopenStreamSync", nullptr, reinterpret_cast(FdopenStreamAni::FdopenStreamSync) }, + ani_native_function { "fsyncSync", nullptr, reinterpret_cast(FsyncAni::FsyncSync) }, + ani_native_function { "getxattrSync", nullptr, reinterpret_cast(XattrAni::GetXattrSync) }, ani_native_function { "listFileSync", nullptr, reinterpret_cast(ListFileAni::ListFileSync) }, + ani_native_function { "lseekSync", nullptr, reinterpret_cast(LseekAni::LseekSync) }, + ani_native_function { "lstatSync", nullptr, reinterpret_cast(LstatAni::LstatSync) }, ani_native_function { "mkdirSync", mkdirCtorSig0.c_str(), reinterpret_cast(MkdirkAni::MkdirSync0) }, ani_native_function { "mkdirSync", mkdirCtorSig1.c_str(), reinterpret_cast(MkdirkAni::MkdirSync1) }, + ani_native_function { "mkdtempSync", nullptr, reinterpret_cast(MkdtempAni::MkdtempSync) }, + ani_native_function { "movedirSync", nullptr, reinterpret_cast(MoveDirAni::MoveDirSync) }, ani_native_function { "moveFileSync", nullptr, reinterpret_cast(MoveAni::MoveFileSync) }, ani_native_function { "openSync", nullptr, reinterpret_cast(OpenAni::OpenSync) }, + ani_native_function { "readlinesSync", nullptr, reinterpret_cast(ReadLinesAni::ReadLinesSync) }, ani_native_function { "readSync", nullptr, reinterpret_cast(ReadAni::ReadSync) }, ani_native_function { "readTextSync", nullptr, reinterpret_cast(ReadTextAni::ReadTextSync) }, + ani_native_function { "renameSync", nullptr, reinterpret_cast(RenameAni::RenameSync) }, ani_native_function { "rmdirSync", nullptr, reinterpret_cast(RmdirAni::RmdirSync) }, + ani_native_function { "setxattrSync", nullptr, reinterpret_cast(XattrAni::SetXattrSync) }, ani_native_function { "statSync", nullptr, reinterpret_cast(StatAni::StatSync) }, + ani_native_function { "symlinkSync", nullptr, reinterpret_cast(SymlinkAni::SymlinkSync) }, ani_native_function { "truncateSync", nullptr, reinterpret_cast(TruncateAni::TruncateSync) }, ani_native_function { "unlinkSync", nullptr, reinterpret_cast(UnlinkAni::UnlinkSync) }, + ani_native_function { "utimes", nullptr, reinterpret_cast(UtimesAni::Utimes) }, ani_native_function { "writeSync", nullptr, reinterpret_cast(WriteAni::WriteSync) }, }; return BindClass(env, classDesc, methods); @@ -110,11 +241,41 @@ static ani_status DoBindMethods(ani_env *env) return status; }; + if ((status = BindReaderIteratorMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native methods for ReaderIterator Class"); + return status; + }; + if ((status = BindStatClassMethods(env)) != ANI_OK) { HILOGE("Cannot bind native methods for Stat Class!"); return status; }; + if ((status = BindRafFileMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native methods for RafFile Class"); + return status; + }; + + if ((status = BindStreamMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native methods for Stream Class!"); + return status; + }; + + if ((status = BindTaskSignalClassMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native methods for TaskSignal Class!"); + return status; + }; + + if ((status = BindWatcherClassMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native methods for Watcher Class"); + return status; + }; + + if ((status = BindAtomicFileMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native methods for AtomicFile Class!"); + return status; + }; + return ANI_OK; } 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 5de05d13c16f74668df53433be2c1f8fdb6bccda..bf94fd6285a8ef35ed503cb5cddc519f1d98242b 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 @@ -13,7 +13,6 @@ * limitations under the License. */ import { BusinessError, AsyncCallback } from '@ohos.base'; -// import stream from '@ohos.util.stream'; const UNKNOWN_ERR: number = 13900042 const UNKNOWN_MSG: string = "Unknown error" @@ -47,8 +46,8 @@ function access(path: string, mode?: AccessModeType): Promise { promise.then((ret: NullishType): void => { let result = ret as boolean; resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -62,8 +61,8 @@ function access(path: string, callback: AsyncCallback): void { e.code = 0; let result = ret as boolean; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, false); + }).catch((e: Error): void => { + callback(e as BusinessError, false); }); } @@ -75,8 +74,8 @@ function access(path: string, mode: AccessModeType, flag: AccessFlagType): Promi promise.then((ret: NullishType): void => { let result = ret as boolean; resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }) } @@ -94,8 +93,8 @@ function close(file: number | File): Promise { let promise = taskpool.execute((file: number | File): undefined => FileIoImpl.closeSync(file), file); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -106,8 +105,8 @@ function close(file: number | File, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -121,8 +120,8 @@ function connectDfs(networkId: string, listeners: DfsListeners): Promise { FileIoImpl.connectDfs(networkId, listeners), networkId, listeners); promise.then((): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -132,8 +131,8 @@ function disconnectDfs(networkId: string): Promise { let promise = taskpool.execute((networkId: string): void => FileIoImpl.disConnectDfs(networkId), networkId); promise.then((): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -150,8 +149,8 @@ function getxattr(path: string, key: string): Promise { promise.then((ret: NullishType): void => { let result = ret as string; resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -171,8 +170,8 @@ function copyDir(src: string, dest: string, mode?: number): Promise { FileIoImpl.copyDirSync(src, dest, mode), src, dest, mode); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError>): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError>); }); }); } @@ -185,8 +184,8 @@ function copyDir(src: string, dest: string, callback: AsyncCallback(0); callback(e, undefined); - }).catch((e: BusinessError>): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError>, undefined); }); } @@ -198,8 +197,8 @@ function copyDir(src: string, dest: string, mode: number, callback: AsyncCallbac e.code = 0; e.data = new Array(0); callback(e, undefined); - }).catch((e: BusinessError>): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError>, undefined); }); } @@ -237,7 +236,7 @@ function fdatasync(fd: number): Promise { let promise = taskpool.execute((fd: number): undefined => FileIoImpl.fdatasyncSync(fd), fd); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { reject(e as BusinessError); }); }); @@ -249,8 +248,8 @@ function fdatasync(fd: number, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -273,7 +272,7 @@ function mkdir(path: string): Promise { let promise = taskpool.execute((path: string): undefined => mkdirSync1(path), path); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { reject(e as BusinessError); }); }); @@ -285,8 +284,8 @@ function mkdir(path: string, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -309,8 +308,8 @@ function mkdir(path: string, recursion: boolean, callback: AsyncCallback): let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -326,8 +325,8 @@ function moveDir(src: string, dest: string, mode?: number): Promise { }, src, dest, mode); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError>): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError>); }); }) } @@ -341,8 +340,8 @@ function moveDir(src: string, dest: string, callback: AsyncCallback(0); callback(e, undefined); - }).catch((e: BusinessError>): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError>, undefined); }); } @@ -355,8 +354,8 @@ function moveDir(src: string, dest: string, mode: number, callback: AsyncCallbac e.code = 0; e.data = new Array(0); callback(e, undefined); - }).catch((e: BusinessError>): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError>, undefined); }); } @@ -393,8 +392,8 @@ function mkdtemp(prefix: string): Promise { promise.then((ret: NullishType): void => { let result = ret as string; resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -408,8 +407,8 @@ function mkdtemp(prefix: string, callback: AsyncCallback): void { e.code = 0; let result = ret as string; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, ""); + }).catch((e: Error): void => { + callback(e as BusinessError, ""); }); } @@ -424,8 +423,8 @@ function moveFile(src: string, dest: string, mode?: number): Promise { }, src, dest, mode); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -438,8 +437,8 @@ function moveFile(src: string, dest: string, mode: number, callback: AsyncCallba let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -451,8 +450,8 @@ function moveFile(src: string, dest: string, callback: AsyncCallback): voi let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -468,8 +467,8 @@ function open(path: String, mode?: number): Promise { promise.then((ret: NullishType): void => { let file = ret as File; resolve(file); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -483,9 +482,9 @@ function open(path: String, mode: number, callback: AsyncCallback): e.code = 0; let file = ret as File; callback(e, file); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { let f: File = new FileInner(0); - callback(e, f); + callback(e as BusinessError, f); }); } @@ -498,9 +497,9 @@ function open(path: String, callback: AsyncCallback): void { e.code = 0; let file = ret as File; callback(e, file); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { let f: File = new FileInner(0); - callback(e, f); + callback(e as BusinessError, f); }); } @@ -516,8 +515,8 @@ function write(fd: number, buffer: string | ArrayBuffer, options?: WriteOptions) promise.then((ret: NullishType): void => { let result = ret as number resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -532,8 +531,8 @@ function write(fd: number, buffer: string | ArrayBuffer, options: WriteOptions, e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -546,8 +545,8 @@ function write(fd: number, buffer: string | ArrayBuffer, callback: AsyncCallback e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -563,8 +562,8 @@ function read(fd: number, buffer: ArrayBuffer, options?: ReadOptions): Promise { let result = ret as number; resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -578,8 +577,8 @@ function read(fd: number, buffer: ArrayBuffer, callback: AsyncCallback { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -592,8 +591,8 @@ function read(fd: number, buffer: ArrayBuffer, options: ReadOptions, callback: A e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -610,8 +609,8 @@ function readLines(filePath: string, options?: Options): Promise promise.then((ret: NullishType): void => { let it = ret as ReaderIterator; resolve(it); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -625,9 +624,9 @@ function readLines(filePath: string, callback: AsyncCallback): v e.code = 0; let it = ret as ReaderIterator; callback(e, it); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { let r: ReaderIterator = new ReaderIteratorInner(0); - callback(e, r); + callback(e as BusinessError, r); }); } @@ -640,9 +639,9 @@ function readLines(filePath: string, options: Options, callback: AsyncCallback { + }).catch((e: Error): void => { let r: ReaderIterator = new ReaderIteratorInner(0); - callback(e, r); + callback(e as BusinessError, r); }); } @@ -656,8 +655,8 @@ function rmdir(path: string): Promise { let promise = taskpool.execute((path: string): void => FileIoImpl.rmdirSync(path), path); promise.then((ret: NullishType) => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -668,8 +667,8 @@ function rmdir(path: string, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -684,8 +683,8 @@ function truncate(file: string | number, len?: number): Promise { }, file, len); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }) } @@ -698,8 +697,8 @@ function truncate(file: string | number, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -711,8 +710,8 @@ function truncate(file: string | number, len: number, callback: AsyncCallback(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -726,8 +725,8 @@ function unlink(path: string): Promise { let promise = taskpool.execute((path: string): undefined => unlinkSync(path), path); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -738,8 +737,8 @@ function unlink(path: string, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -751,9 +750,9 @@ function readText(filePath: string, options?: ReadTextOptions): Promise promise.then((ret: NullishType): void => { let r = ret as string; resolve(r); - }).catch((e: BusinessError): void => { - reject(e); - }); + }).catch((e: Error): void => { + reject(e as BusinessError); + }); }); } @@ -766,8 +765,8 @@ function readText(filePath: string, callback: AsyncCallback): void { e.code = 0; let r = ret as string; callback(e, r); - }).catch((e: BusinessError): void => { - callback(e, ""); + }).catch((e: Error): void => { + callback(e as BusinessError, ""); }); } @@ -780,8 +779,8 @@ function readText(filePath: string, options: ReadTextOptions, callback: AsyncCal e.code = 0; let r = ret as string; callback(e, r); - }).catch((e: BusinessError): void => { - callback(e, ""); + }).catch((e: Error): void => { + callback(e as BusinessError, ""); }); } @@ -797,8 +796,8 @@ function listFile(path: string, options?: ListFileOptions): Promise { promise.then((ret: NullishType): void => { let r = ret as string[]; resolve(r); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -812,8 +811,8 @@ function listFile(path: string, callback: AsyncCallback): void { e.code = 0; let r = ret as string[]; callback(e, r); - }).catch((e: BusinessError): void => { - callback(e, []); + }).catch((e: Error): void => { + callback(e as BusinessError, []); }); } @@ -826,8 +825,8 @@ function listFile(path: string, options: ListFileOptions, callback: AsyncCallbac e.code = 0; let r = ret as string[]; callback(e, r); - }).catch((e: BusinessError): void => { - callback(e, []); + }).catch((e: Error): void => { + callback(e as BusinessError, []); }); } @@ -851,8 +850,8 @@ function stat(file: string | number): Promise { promise.then((ret: NullishType): void => { let r = ret as Stat; resolve(r); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -866,8 +865,8 @@ function stat(file: string | number, callback: AsyncCallback): void e.code = 0; let r = ret as Stat; callback(e, r); - }).catch((e: BusinessError): void => { - callback(e, new StatInner(0)); + }).catch((e: Error): void => { + callback(e as BusinessError, new StatInner(0)); }); } @@ -882,8 +881,8 @@ function fsync(fd: number): Promise { }, fd); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -896,8 +895,8 @@ function fsync(fd: number, callback: AsyncCallback): void { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -913,8 +912,8 @@ function symlink(target: string, srcPath: string): Promise { }, target, srcPath); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -929,8 +928,8 @@ function rename(oldPath: string, newPath: string): Promise { }, oldPath, newPath); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -943,8 +942,8 @@ function rename(oldPath: string, newPath: string, callback: AsyncCallback) let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -964,8 +963,8 @@ function createRandomAccessFile(file: string | File, mode?: number, promise.then((ret: NullishType): void => { let raffile = ret as RandomAccessFileInner; resolve(raffile); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -978,8 +977,8 @@ function fdopenStream(fd: number, mode: string): Promise { promise.then((ret: NullishType): void => { let stream = ret as Stream; resolve(stream); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -994,7 +993,7 @@ function setxattr(path: string, key: string, value: string): Promise { FileIoImpl.setxattrSync(path, key, value), path, key, value); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { reject(e as BusinessError); }); }); @@ -1009,9 +1008,9 @@ function createRandomAccessFile(file: string | File, callback: AsyncCallback { + }).catch((e: Error): void => { let f: RandomAccessFile = new RandomAccessFileInner(0); - callback(e, f); + callback(e as BusinessError, f); }); } @@ -1025,9 +1024,9 @@ function createRandomAccessFile(file: string | File, mode: number, e.code = 0; let raffile = ret as RandomAccessFile; callback(e, raffile); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { let f: RandomAccessFile = new RandomAccessFileInner(0); - callback(e, f); + callback(e as BusinessError, f); }); } @@ -1040,9 +1039,9 @@ function fdopenStream(fd: number, mode: string, callback: AsyncCallback) e.code = 0; let stream = ret as Stream; callback(e, stream); - }).catch((e: BusinessError): void => { + }).catch((e: Error): void => { let r: Stream = new StreamInner(0); - callback(e, r); + callback(e as BusinessError, r); }); } @@ -1058,8 +1057,8 @@ function createStream(path: string, mode: string): Promise { promise.then((ret: NullishType): void => { let stream = ret as Stream; resolve(stream); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1073,9 +1072,9 @@ function createStream(path: string, mode: string, callback: AsyncCallback { + }).catch((e: Error): void => { let r: Stream = new StreamInner(0); - callback(e, r); + callback(e as BusinessError, r); }); } @@ -1083,14 +1082,6 @@ function createStreamSync(path: string, mode: string): Stream { return FileIoImpl.createStreamSync(path, mode); } -// function createReadStream(path: string, options?: ReadStreamOptions): ReadStream { -// return new ReadStream(path, options) -// } - -// function createWriteStream(path: string, options?: WriteStreamOptions): WriteStream { -// return new WriteStream(path, options); -// } - function createWatcher(path: string, events: number, listener: WatchEventListener): Watcher { return FileIoImpl.createWatcherSync(path, events, listener); } @@ -1103,8 +1094,8 @@ function symlink(target: string, srcPath: string, callback: AsyncCallback) let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1130,8 +1121,8 @@ function lstat(path: string): Promise { let r = ret as Stat; resolve(r); } - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1151,8 +1142,8 @@ function lstat(path: string, callback: AsyncCallback): void { let r = ret as Stat; callback(e, r); } - }).catch((e: BusinessError): void => { - callback(e, new StatInner(0)); + }).catch((e: Error): void => { + callback(e as BusinessError, new StatInner(0)); }); } function copyFile(src: string | number, dest: string | number, mode?: number): Promise { @@ -1161,8 +1152,8 @@ function copyFile(src: string | number, dest: string | number, mode?: number): P FileIoImpl.copyFileSync(src, dest, mode), src, dest, mode); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1173,8 +1164,8 @@ function copy(srcUri: string, destUri: string, options?: CopyOptions): Promise { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1186,8 +1177,8 @@ function copyFile(src: string | number, dest: string | number, mode: number, cal let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1198,8 +1189,8 @@ function copy(srcUri: string, destUri: string, options: CopyOptions, callback: A let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1210,8 +1201,8 @@ function copyFile(src: string | number, dest: string | number, callback: AsyncCa let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1222,8 +1213,8 @@ function copy(srcUri: string, destUri: string, callback: AsyncCallback): v let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1263,20 +1254,31 @@ 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 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); + } catch (e: Error) { + reject(e as BusinessError); + } }); } + } export interface CopyOptions { @@ -1309,8 +1311,6 @@ export interface RandomAccessFile { read(buffer: ArrayBuffer, callback: AsyncCallback): void; read(buffer: ArrayBuffer, options: ReadOptions, callback: AsyncCallback): void; readSync(buffer: ArrayBuffer, options?: ReadOptions): number; - // getReadStream(): ReadStream; - // getWriteStream(): WriteStream; } export class RandomAccessFileInner implements RandomAccessFile { @@ -1331,7 +1331,7 @@ export class RandomAccessFileInner implements RandomAccessFile { } native setFilePointer0(filePointer: number): void; - + native close(): void; writeSync(buffer: ArrayBuffer | string, options?: WriteOptions): number { @@ -1350,8 +1350,8 @@ export class RandomAccessFileInner implements RandomAccessFile { promise.then((ret: NullishType): void => { let result = ret as number resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1365,8 +1365,8 @@ export class RandomAccessFileInner implements RandomAccessFile { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -1379,8 +1379,8 @@ export class RandomAccessFileInner implements RandomAccessFile { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -1400,8 +1400,8 @@ export class RandomAccessFileInner implements RandomAccessFile { promise.then((ret: NullishType): void => { let result = ret as number; resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1415,8 +1415,8 @@ export class RandomAccessFileInner implements RandomAccessFile { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -1429,13 +1429,11 @@ export class RandomAccessFileInner implements RandomAccessFile { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } - // native getReadStream(): ReadStream; - // native getWriteStream(): WriteStream; } export interface File { @@ -1474,8 +1472,8 @@ export class FileInner implements File { }, exclusive); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1488,8 +1486,8 @@ export class FileInner implements File { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1501,8 +1499,8 @@ export class FileInner implements File { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1590,7 +1588,7 @@ export class StatInner implements Stat { this.nativeStat = stat; } } - + native isBlockDevice(): boolean; native isCharacterDevice(): boolean; native isDirectory(): boolean; @@ -1632,8 +1630,8 @@ export class StreamInner implements Stream { let promise = taskpool.execute((): undefined => this.closeSync()); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1644,8 +1642,8 @@ export class StreamInner implements Stream { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1656,8 +1654,8 @@ export class StreamInner implements Stream { let promise = taskpool.execute((): undefined => this.flushSync()); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1668,8 +1666,8 @@ export class StreamInner implements Stream { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -1683,8 +1681,8 @@ export class StreamInner implements Stream { promise.then((ret: NullishType): void => { let result = ret as number resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1698,8 +1696,8 @@ export class StreamInner implements Stream { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -1712,8 +1710,8 @@ export class StreamInner implements Stream { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -1727,8 +1725,8 @@ export class StreamInner implements Stream { promise.then((ret: NullishType): void => { let result = ret as number resolve(result); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -1742,8 +1740,8 @@ export class StreamInner implements Stream { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } @@ -1756,163 +1754,15 @@ export class StreamInner implements Stream { e.code = 0; let result = ret as number; callback(e, result); - }).catch((e: BusinessError): void => { - callback(e, 0); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); }); } - + native readSync(buffer: ArrayBuffer, options?: ReadOptions): number; native seek(offset: number, whence?: number): number; } -// export class ReadStream extends stream.Readable { -// path: string; -// bytesRead: number; -// private offset: number; -// private start?: number; -// private end?: number; -// private stream?: Stream; - -// constructor(path: string, options?: ReadStreamOptions) { -// super(); -// this.path = path; -// this.bytesRead = 0; -// this.start = options?.start; -// this.end = options?.end; -// this.stream = createStreamSync(this.path, 'r'); -// this.offset = this.start ?? 0; -// } - -// seek(offset: number, whence?: WhenceType): number { -// if (whence === undefined) { -// let off = this.stream?.seek(offset); -// if (off !== undefined) { -// this.offset = off -// } -// } else { -// let off = this.stream?.seek(offset, whence); -// if (off !== undefined) { -// this.offset = off -// } -// } -// return this.offset; -// } - -// close(): void { -// this.stream?.close(); -// } - -// doInitialize(callback: () => void): void { -// callback(); -// } - -// doRead(size: number): void { -// let readSize = size; -// let end = this.end -// if (end !== undefined) { -// if (this.offset > end) { -// this.push(null); -// return; -// } -// if (this.offset + readSize > end) { -// readSize = end - this.offset; -// } -// } -// let buffer = new ArrayBuffer(readSize); -// const off = this.offset; -// this.offset += readSize; -// this.stream?.read(buffer, { offset: off, length: readSize }) -// .then((readOut: number) => { -// if (readOut > 0) { -// this.bytesRead += readOut; -// this.push(new Uint8Array(buffer.slice(0, readOut))); -// } -// if (readOut !== readSize || readOut < size) { -// this.offset = this.offset - readSize + readOut; -// this.push(null); -// } -// }); -// } -// } - -// export class WriteStream extends stream.Writable { -// path: string; -// bytesWritten: number; -// private offset: number; -// private mode: string; -// private start?: number; -// private stream?: Stream; - -// constructor(path: string, options?: WriteStreamOptions) { -// super(); -// this.path = path; -// this.bytesWritten = 0; -// this.start = options?.start; -// this.mode = this.convertOpenMode(options?.mode); -// this.stream = createStreamSync(this.path, this.mode); -// this.offset = this.start ?? 0; -// } - -// seek(offset: number, whence?: WhenceType): number { -// if (whence === undefined) { -// let off = this.stream?.seek(offset); -// if (off !== undefined) { -// this.offset = off -// } -// } else { -// let off = this.stream?.seek(offset, whence); -// if (off !== undefined) { -// this.offset = off -// } -// } -// return this.offset; -// } - -// close(): void { -// this.stream?.close(); -// } - -// closeSync(): void { -// this.stream?.closeSync(); -// } - -// doInitialize(callback: () => void): void { -// callback(); -// } - -// doWrite(chunk: string | ArrayBuffer, encoding: string, callback: () => void): void { -// this.stream?.write(chunk, { offset: this.offset }) -// .then((writeIn: number) => { -// this.offset += writeIn; -// this.bytesWritten += writeIn; -// callback(); -// }) -// .finally(() => { -// this.stream?.flush(); -// }); -// } - -// convertOpenMode(mode?: number): string { -// let modeStr = 'w'; -// if (mode === undefined) { -// return modeStr; -// } -// if ((mode as number) & fileIo.OpenMode.WRITE_ONLY) { -// modeStr = 'w'; -// } -// if ((mode as number) & fileIo.OpenMode.READ_WRITE) { -// modeStr = 'w+'; -// } -// if (((mode as number) & fileIo.OpenMode.WRITE_ONLY) && ((mode as number) & fileIo.OpenMode.APPEND)) { -// modeStr = 'a'; -// } -// if (((mode as number) & fileIo.OpenMode.READ_WRITE) && ((mode as number) & fileIo.OpenMode.APPEND)) { -// modeStr = 'a+'; -// } -// return modeStr; -// } -// } - export class AtomicFile { static { loadLibrary("ani_file_fs"); @@ -1920,43 +1770,13 @@ export class AtomicFile { private nativePtr: long = 0; private native getPath(): string; - // private writeStream: WriteStream | null = null; native constructor(path: string); native getBaseFile(): File; - // native openRead(): ReadStream; - native readFully(): ArrayBuffer; - // native nativeStartWrite(): WriteStream; - // startWrite(): WriteStream { - // let ws = this.nativeStartWrite(); - // this.writeStream = ws; - // return ws; - // } - - // native nativeFinishWrite(): void; - // finishWrite(): void { - // if (!this.writeStream) { - // throw createBusinessError(UNKNOWN_ERR, UNKNOWN_MSG); - // } - // this.writeStream?.close(); - // this.nativeFinishWrite(); - // this.writeStream = null; - // }; - - // native nativeFailWrite(): void; - // failWrite(): void { - // if (!this.writeStream) { - // throw createBusinessError(UNKNOWN_ERR, UNKNOWN_MSG); - // } - // this.writeStream?.close(); - // this.nativeFailWrite(); - // this.writeStream = null; - // }; - native delete(): void; } @@ -2119,15 +1939,15 @@ export class FileIoImpl { static native createStreamSync(path: string, mode: string): fileIo.Stream; static native createWatcherSync(path: string, events: number, listener: WatchEventListener): fileIo.Watcher; - + static native fdopenStreamSync(fd: number, mode: string): fileIo.Stream; - + static native dup(fd: number): fileIo.File; static native listFileSync(path: string, options?: ListFileOptions): string[]; static native lstatSync(path: string): fileIo.Stat; - + static native lseekSync(fd: number, offset: number, whence?: fileIo.WhenceType): number; static native mkdirSync(path: string): void; @@ -2143,7 +1963,7 @@ export class FileIoImpl { static native openSync(path: String, mode?: number): fileIo.File; static native readlinesSync(filePath: string, options?: Options): fileIo.ReaderIterator; - + static native readSync(fd: number, buffer: ArrayBuffer, options?: ReadOptions): number; static native readTextSync(filePath: string, options?: ReadTextOptions): string; diff --git a/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.cpp b/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.cpp index 07b6eef169ecf1b47f5540f13bf036fbd8c7dc0d..a82d1b62752a2cbccd7d2c9825d530f31c9cddec 100644 --- a/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.cpp @@ -28,7 +28,7 @@ namespace OHOS { namespace FileManagement { namespace ModuleFileIO { namespace ANI { -namespace fs = filesystem; +namespace fs = std::filesystem; using namespace std; using namespace OHOS::FileManagement::ModuleFileIO; using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; diff --git a/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.h b/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.h index 5a2c8d02c2ba4754b23fa978b785cb11dafee38e..55eaf2a94f99d523f2ab3b66b591271ad7e60619 100644 --- a/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_atomicfile/ani/atomicfile_ani.h @@ -40,4 +40,4 @@ public: } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_ATOMICFILE_ANI_ATOMICFILE_ANI_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_ATOMICFILE_ANI_ATOMICFILE_ANI_H diff --git a/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp b/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp index a220f84baa93943aaae7d349f7ff02c95de5fbc9..953755eb25e79b383a94c5552e956520e719a761 100644 --- a/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/class_randomaccessfile/ani/randomaccessfile_ani.cpp @@ -285,15 +285,15 @@ static ani_string GetFilePath(ani_env *env, const int fd) static ani_object CreateReadStreamOptions(ani_env *env, int64_t start, int64_t end) { - static const char *className = FS::ReadStreamOptionsInner::classType; + static const char *className = FS::ReadStreamOptionsInner::classDesc.c_str(); ani_class cls; if (ANI_OK != env->FindClass(className, &cls)) { HILOGE("Cannot find class %{public}s", className); return nullptr; } ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, FS::ReadStreamOptionsInner::ctorDesc, - FS::ReadStreamOptionsInner::ctorSig, &ctor)) { + if (ANI_OK != env->Class_FindMethod(cls, FS::ReadStreamOptionsInner::ctorDesc.c_str(), + FS::ReadStreamOptionsInner::ctorSig.c_str(), &ctor)) { HILOGE("Cannot find constructor method for class %{public}s", className); return nullptr; } @@ -329,15 +329,15 @@ static ani_object CreateReadStreamOptions(ani_env *env, int64_t start, int64_t e static ani_object CreateWriteStreamOptions(ani_env *env, int64_t start, int flags) { - static const char *className = FS::WriteStreamOptionsInner::classType; + static const char *className = FS::WriteStreamOptionsInner::classDesc.c_str(); ani_class cls; if (ANI_OK != env->FindClass(className, &cls)) { HILOGE("Cannot find class %{public}s", className); return nullptr; } ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, FS::WriteStreamOptionsInner::ctorDesc, - FS::WriteStreamOptionsInner::ctorSig, &ctor)) { + if (ANI_OK != env->Class_FindMethod(cls, FS::WriteStreamOptionsInner::ctorDesc.c_str(), + FS::WriteStreamOptionsInner::ctorSig.c_str(), &ctor)) { HILOGE("Cannot find constructor method for class %{public}s", className); return nullptr; } diff --git a/interfaces/kits/js/src/mod_fs/class_randomaccessfile/fs_randomaccessfile.h b/interfaces/kits/js/src/mod_fs/class_randomaccessfile/fs_randomaccessfile.h index 024cf25b7db7d2bfdfaae1b591abf1a6c4bd8664..3391b3658e27ff230066f6deb716f2f1355964e5 100644 --- a/interfaces/kits/js/src/mod_fs/class_randomaccessfile/fs_randomaccessfile.h +++ b/interfaces/kits/js/src/mod_fs/class_randomaccessfile/fs_randomaccessfile.h @@ -69,6 +69,7 @@ public: FsResult WriteSync(const ArrayBuffer &buffer, const optional &options = nullopt) const; FsResult ReadSync(ArrayBuffer &buffer, const optional &options = nullopt) const; FsResult CloseSync() const; + FsResult GetFD() const; FsResult GetFPointer() const; diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h index 13b2f7556bd5f2313b36c5a96f8fb42252d3e0d1..1b66d1d00f98e09e845ac518a6d2a025247d3234 100644 --- a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_ani.h @@ -36,4 +36,4 @@ public: } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_ANI_READER_ITERATOR_ANI_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_ANI_READER_ITERATOR_ANI_H diff --git a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h index 31bf73e9cef76868f054bdc0b5d3158ef2cb7606..87326ca81554546ba7b2b774cb064a442b4e89a6 100644 --- a/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h +++ b/interfaces/kits/js/src/mod_fs/class_readeriterator/ani/reader_iterator_result_ani.h @@ -34,4 +34,4 @@ public: } // namespace FileManagement } // namespace OHOS -#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_ANI_READER_ITERATOR_RESULT_ANI_H \ No newline at end of file +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_READERITERATOR_ANI_READER_ITERATOR_RESULT_ANI_H diff --git a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp index b381e97bfc0e426bd681fe03444576e1f827602e..6f92f562fb0f0f8ad25b48bea4d72cc9f9a9d2c1 100644 --- a/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/class_stream/stream_n_exporter.cpp @@ -27,6 +27,7 @@ #include "common_func.h" #include "file_utils.h" #include "filemgmt_libhilog.h" +#include "rust_file.h" #include "stream_entity.h" namespace OHOS { 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 0ac364b3572155a9c64cdca95ba822ea8d1d6b8b..2b1229a6947fdefd5f18346d83760f2ca312781e 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 @@ -38,7 +38,6 @@ void TaskSignalAni::Cancel(ani_env *env, [[maybe_unused]] ani_object object) ErrorHandler::Throw(env, EINVAL); return; } - auto ret = copySignal->Cancel(); if (!ret.IsSuccess()) { HILOGE("Cannot Cancel!"); @@ -56,7 +55,6 @@ void TaskSignalAni::OnCancel(ani_env *env, [[maybe_unused]] ani_object object) ErrorHandler::Throw(env, EINVAL); return; } - auto ret = copySignal->OnCancel(); if (!ret.IsSuccess()) { HILOGE("Cannot Cancel!"); 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 5bb6daff863409042cf7df87f461d6149f5bd1e2..8f533889c3ee78210c3aa97f09b4b74a120da02c 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 @@ -43,7 +43,6 @@ void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const 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."); @@ -54,7 +53,6 @@ void TaskSignalListenerAni::SendCancelEvent(const string &filepath) const 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: %{public}d", ret); 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 index 76bf8cd8700dafbc31b9abb6be22bf832ab0ec03..d9b4b6ffe4608122c64ec35f99b2a6f6e1b598d2 100644 --- 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 @@ -51,7 +51,6 @@ FsResult FsTaskSignal::Cancel() HILOGE("Failed to get taskSignal"); return FsResult::Error(EINVAL); } - auto ret = taskSignal_->Cancel(); if (ret != ERRNO_NOERR) { HILOGE("Failed to cancel the task."); diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_ani.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39d11f4968ca81336a673866d5a003b442a103d6 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_ani.cpp @@ -0,0 +1,68 @@ +/* + * 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_watcher_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "fs_watcher.h" +#include "fs_watcher_wrapper.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace std; + +void FsWatcherAni::Start(ani_env *env, [[maybe_unused]] ani_object object) +{ + auto watcher = FsWatcherWrapper::Unwrap(env, object); + if (watcher == nullptr) { + HILOGE("Cannot unwrap watcher!"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return; + } + auto ret = watcher->Start(); + if (!ret.IsSuccess()) { + HILOGE("Cannot start watcher!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} + +void FsWatcherAni::Stop(ani_env *env, [[maybe_unused]] ani_object object) +{ + auto watcher = FsWatcherWrapper::Unwrap(env, object); + if (watcher == nullptr) { + HILOGE("Cannot unwrap watcher!"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return; + } + auto ret = watcher->Stop(); + if (!ret.IsSuccess()) { + HILOGE("Cannot stop watcher!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_ani.h b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..e6badfc7b61fd3428ea621f57c95fe21d421c297 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_ani.h @@ -0,0 +1,36 @@ +/* + * 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_ANI_FS_WATCHER_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_FS_WATCHER_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class FsWatcherAni final { +public: + static void Start(ani_env *env, [[maybe_unused]] ani_object object); + static void Stop(ani_env *env, [[maybe_unused]] ani_object object); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_FS_WATCHER_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_wrapper.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_wrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79d6fb1dcec57fd9324c82ccf1a20d4c88309431 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_wrapper.cpp @@ -0,0 +1,73 @@ +/* + * 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_watcher_wrapper.h" + +#include "ani_signature.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +FsWatcher *FsWatcherWrapper::Unwrap(ani_env *env, ani_object object) +{ + ani_long nativePtr; + auto ret = env->Object_GetFieldByName_Long(object, "nativePtr", &nativePtr); + if (ret != ANI_OK) { + HILOGE("Unwrap fsWatcher err: %{private}d", ret); + return nullptr; + } + uintptr_t ptrValue = static_cast(nativePtr); + FsWatcher *watcher = reinterpret_cast(ptrValue); + return watcher; +} + +ani_object FsWatcherWrapper::Wrap(ani_env *env, const FsWatcher *watcher) +{ + if (watcher == nullptr) { + HILOGE("FsWatcher pointer is null!"); + return nullptr; + } + auto classDesc = FS::WatcherInner::classDesc.c_str(); + ani_class cls; + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %s", classDesc); + return nullptr; + } + auto ctorDesc = FS::WatcherInner::ctorDesc.c_str(); + auto ctorSig = FS::WatcherInner::ctorSig.c_str(); + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %s", classDesc); + return nullptr; + } + ani_long ptr = static_cast(reinterpret_cast(watcher)); + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, ptr)) { + HILOGE("New %s obj Failed!", classDesc); + return nullptr; + } + return obj; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_wrapper.h b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..15d24f94e5453c6eafe1e95c6664c2e05bc11ef4 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/fs_watcher_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_WATCHER_ANI_FS_WATCHER_WRAPPER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_FS_WATCHER_WRAPPER_H + +#include +#include "fs_watcher.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class FsWatcherWrapper final { +public: + static FsWatcher *Unwrap(ani_env *env, ani_object object); + static ani_object Wrap(ani_env *env, const FsWatcher *watcher); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_FS_WATCHER_WRAPPER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_listener.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_listener.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36ac7517d6d286f627a4ffd4e5c05002e49928d0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_listener.cpp @@ -0,0 +1,114 @@ +/* + * 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 "watch_event_listener.h" + +#include +#include "ani_helper.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" +#include "watch_event_wrapper.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { +using namespace std; + +bool WatchEventListener::IsStrictEquals(const shared_ptr &other) const +{ + if (other->GetClassName() != className_) { + return false; + } + + const auto otherListener = static_pointer_cast(other); + if (!otherListener) { + HILOGE("Cannot convert IWatcherCallback to WatchEventListener"); + return false; + } + + ani_env *env = AniHelper::GetThreadEnv(vm); + if (!env) { + HILOGE("Current object's env is null"); + return false; + } + + ani_boolean isSame = false; + ani_status status = env->Reference_StrictEquals(callback, otherListener->callback, &isSame); + if (status != ANI_OK) { + HILOGE("Compare ref for strict equality failed. status = %{public}d", static_cast(status)); + return false; + } + return isSame; +} + +void WatchEventListener::InvokeCallback(const string &fileName, uint32_t event, uint32_t cookie) const +{ + auto watchEvent = CreateSharedPtr(); + if (watchEvent == nullptr) { + HILOGE("Failed to request heap memory."); + return; + } + + watchEvent->fileName = fileName; + watchEvent->event = event; + watchEvent->cookie = cookie; + auto task = [this, watchEvent]() { SendWatchEvent(*watchEvent); }; + AniHelper::SendEventToMainThread(task); +} + +inline static const int32_t ANI_SCOPE_SIZE = 16; + +void WatchEventListener::SendWatchEvent(const WatchEvent &watchEvent) const +{ + if (vm == nullptr) { + HILOGE("Cannot send WatchEvent because the vm is null."); + return; + } + if (callback == nullptr) { + HILOGE("Cannot send WatchEvent because the callback is null."); + return; + } + ani_size scopeSize = ANI_SCOPE_SIZE; + ani_env *env = AniHelper::GetThreadEnv(vm); + if (env == nullptr) { + HILOGE("Cannot send WatchEvent because the env is null."); + return; + } + ani_status status = env->CreateLocalScope(scopeSize); + if (status != ANI_OK) { + HILOGE("Failed to creat local scope, status: %{public}d", static_cast(status)); + return; + } + auto evtObj = WatchEventWrapper::Wrap(env, watchEvent); + if (evtObj == nullptr) { + HILOGE("Create WatchEvent obj failed!"); + return; + } + vector args = { static_cast(evtObj) }; + auto argc = args.size(); + ani_ref result; + auto cbObj = static_cast(callback); + 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)); + // continue execution and not exit. + } + status = env->DestroyLocalScope(); + if (status != ANI_OK) { + HILOGE("Failed to destroy local scope, status: %{public}d", static_cast(status)); + return; + } +} + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_listener.h b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..919739228b992670dccb5441781c8fe0db0fe63c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_listener.h @@ -0,0 +1,48 @@ +/* + * 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_ANI_WATCH_EVENT_LISTENER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_WATCH_EVENT_LISTENER_H + +#include + +#include + +#include "fs_watch_entity.h" +#include "i_watcher_callback.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { + +class WatchEventListener final : public IWatcherCallback { +public: + WatchEventListener(ani_vm *vm, const ani_ref &callback) : vm(vm), callback(callback) {} + bool IsStrictEquals(const std::shared_ptr &other) const override; + void InvokeCallback(const std::string &fileName, uint32_t event, uint32_t cookie) const override; + + std::string GetClassName() const override + { + return className_; + } + +private: + inline static const std::string className_ = "WatchEventListener"; + void SendWatchEvent(const WatchEvent &watchEvent) const; + + ani_vm *vm; + ani_ref callback; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_WATCH_EVENT_LISTENER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_wrapper.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_wrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1712f7f1f1ea44307b90f50ccd03e9311824c496 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_wrapper.cpp @@ -0,0 +1,66 @@ +/* + * 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 "watch_event_wrapper.h" + +#include "ani_signature.h" +#include "filemgmt_libhilog.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; + +ani_object WatchEventWrapper::Wrap(ani_env *env, const WatchEvent &evt) +{ + auto classDesc = FS::WatchEventInner::classDesc.c_str(); + ani_class cls; + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %s", classDesc); + return nullptr; + } + auto ctorDesc = FS::WatchEventInner::ctorDesc.c_str(); + auto ctorSig = FS::WatchEventInner::ctorSig.c_str(); + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %s", classDesc); + return nullptr; + } + + auto [succ, fileName] = TypeConverter::ToAniString(env, evt.fileName); + if (!succ) { + HILOGE("Convert fileName to ani string failed!"); + return nullptr; + } + + auto event = static_cast(evt.event); + auto cookie = static_cast(evt.cookie); + + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, fileName, event, cookie)) { + HILOGE("Create %s obj failed!", classDesc); + return nullptr; + } + return obj; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_wrapper.h b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..8e2ca980c9302cccd122711aa7d9648f169904ae --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/ani/watch_event_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_WATCHER_ANI_WATCH_EVENT_WRAPPER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_WATCH_EVENT_WRAPPER_H + +#include +#include +#include "fs_watch_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class WatchEventWrapper final { +public: + static ani_object Wrap(ani_env *env, const WatchEvent &evt); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_ANI_WATCH_EVENT_WRAPPER_H \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..9f77d49df39c7e271a3d9ca53d0e9a9b9418a648 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.cpp @@ -0,0 +1,348 @@ +/* + * 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_file_watcher.h" + +#include +#include +#include +#include +#include + +#include + +#include "filemgmt_libhilog.h" +#include "uv.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +int32_t FsFileWatcher::GetNotifyId() +{ + return notifyFd_; +} + +bool FsFileWatcher::InitNotify() +{ + notifyFd_ = inotify_init(); + if (notifyFd_ < 0) { + HILOGE("Failed to init notify errCode:%{public}d", errno); + return false; + } + eventFd_ = eventfd(0, EFD_CLOEXEC); + if (eventFd_ < 0) { + HILOGE("Failed to init eventfd errCode:%{public}d", errno); + return false; + } + return true; +} + +int32_t FsFileWatcher::StartNotify(shared_ptr info) +{ + if (!info) { + HILOGE("Invalid param: info"); + return EINVAL; + } + + if (notifyFd_ < 0) { + HILOGE("Failed to start notify notifyFd_:%{public}d", notifyFd_); + return EIO; + } + + 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 = 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; + dataCache_.UpdateWatchedEvents(info->fileName, newWd, watchEvents); + return ERRNO_NOERR; +} + +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) { + HILOGE("Failed to start new notify errCode:%{public}d", errno); + return errno; + } + + if (newWd != wd) { + HILOGE("New notify wd is error"); + return EIO; + } + + dataCache_.UpdateWatchedEvents(fileName, wd, watchEvents); + return ERRNO_NOERR; +} + +int32_t FsFileWatcher::CloseNotifyFd() +{ + int32_t closeRet = ERRNO_NOERR; + + 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); + } + eventFd_ = -1; + DestroyTaskThead(); + } + + closed_ = false; + return closeRet; +} + +int32_t FsFileWatcher::CloseNotifyFdLocked() +{ + { + lock_guard lock(readMutex_); + closed_ = true; + if (reading_) { + HILOGE("close while reading"); + return ERRNO_NOERR; + } + } + return CloseNotifyFd(); +} + +int32_t FsFileWatcher::StopNotify(shared_ptr info) +{ + if (!info) { + HILOGE("Invalid param: info"); + return EINVAL; + } + + if (notifyFd_ < 0) { + HILOGE("Failed to stop notify notifyFd_:%{public}d", notifyFd_); + return EIO; + } + + 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, remainingEvents); + } + HILOGE("The Watched file does not exist, and the remaining monitored events will be invalid."); + return ERRNO_NOERR; + } + + // 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_)) { + oldWd = inotify_rm_watch(notifyFd_, info->wd); + } else { + HILOGE("rm watch fail"); + } + } + + if (oldWd == -1) { + int32_t rmErr = errno; + if (access(info->fileName.c_str(), F_OK) == 0) { + HILOGE("Failed to stop notify errCode:%{public}d", rmErr); + dataCache_.RemoveFileWatcher(info->fileName); + CloseNotifyFdLocked(); + return rmErr; + } + } + + dataCache_.RemoveFileWatcher(info->fileName); + return CloseNotifyFdLocked(); +} + +void FsFileWatcher::ReadNotifyEvent() +{ + int32_t len = 0; + 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) { + HILOGE("Read notify event failed! ret: %d", errno); + break; + } + } while (len < 0); + + while (index < len) { + event = reinterpret_cast(buf + index); + NotifyEvent(event); + index += sizeof(struct inotify_event) + static_cast(event->len); + } +} + +void FsFileWatcher::ReadNotifyEventLocked() +{ + { + lock_guard lock(readMutex_); + if (closed_) { + HILOGE("read after close"); + return; + } + reading_ = true; + } + + ReadNotifyEvent(); + + { + lock_guard lock(readMutex_); + reading_ = false; + if (closed_) { + HILOGE("close after read"); + CloseNotifyFd(); + return; + } + } +} + +void FsFileWatcher::AsyncGetNotifyEvent() +{ + lock_guard lock(taskMutex_); + if (!taskRunning_) { + taskRunning_ = true; + taskThead_ = thread(&FsFileWatcher::GetNotifyEvent, this); + } +} + +void FsFileWatcher::GetNotifyEvent() +{ + if (run_) { + return; + } + + run_ = true; + nfds_t nfds = 2; + struct pollfd fds[2] = { { -1 } }; + fds[0].fd = eventFd_; + fds[0].events = POLLIN; + fds[1].fd = notifyFd_; + fds[1].events = POLLIN; + int32_t ret = 0; + + while (run_) { + ret = poll(fds, nfds, pollTimeoutMs); + if (ret > 0) { + if (static_cast(fds[0].revents) & POLLNVAL) { + run_ = false; + 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) { + HILOGE("Failed to poll NotifyFd, errno=%{public}d", errno); + break; + } + // Ignore cases where poll returns 0 (timeout) or EINTR (interrupted system call) + } +} + +bool FsFileWatcher::AddWatcherInfo(shared_ptr info) +{ + if (!info) { + HILOGE("Invalid param: info"); + return false; + } + return dataCache_.AddWatcherInfo(info); +} + +uint32_t FsFileWatcher::RemoveWatcherInfo(shared_ptr info) +{ + if (!info) { + HILOGE("Invalid param: info"); + return EINVAL; + } + return dataCache_.RemoveWatcherInfo(info); +} + +void FsFileWatcher::NotifyEvent(const struct inotify_event *event) +{ + if (!event) { + HILOGE("Invalid inotify event"); + return; + } + + auto [matched, fileName, watcherInfos] = dataCache_.FindWatcherInfos(event->wd, event->mask); + if (!matched) { + HILOGE("Cannot find matched watcherInfos"); + return; + } + + for (const auto &info : watcherInfos) { + if (event->len > 0) { + fileName += "/" + string(event->name); + } + info->TriggerCallback(fileName, event->mask & IN_ALL_EVENTS, event->cookie); + } +} + +bool FsFileWatcher::CheckEventValid(uint32_t event) +{ + if ((event & IN_ALL_EVENTS) == event) { + return true; + } else { + HILOGE("Param event:%{public}x is not valid", event); + return false; + } +} + +void FsFileWatcher::DestroyTaskThead() +{ + if (taskThead_.joinable()) { + if (taskThead_.get_id() != std::this_thread::get_id()) { + taskThead_.join(); + } else { + taskThead_.detach(); + } + } + + { + 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 new file mode 100644 index 0000000000000000000000000000000000000000..57b83d3319f938baffee83d9834144eb3024719f --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_file_watcher.h @@ -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. + */ +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_FILE_WATCHER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_FILE_WATCHER_H + +#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 int32_t BUF_SIZE = 1024; + +class FsFileWatcher : public Singleton { +public: + int32_t GetNotifyId(); + bool InitNotify(); + int32_t StartNotify(shared_ptr info); + int32_t StopNotify(shared_ptr info); + void GetNotifyEvent(); + void AsyncGetNotifyEvent(); + 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); + void NotifyEvent(const struct inotify_event *event); + 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 constexpr int32_t pollTimeoutMs = 500; + + mutex taskMutex_; + mutex readMutex_; + + atomic taskRunning_ = false; + thread taskThead_; + + bool run_ = false; + bool reading_ = false; + bool closed_ = false; + int32_t notifyFd_ = -1; + int32_t eventFd_ = -1; + WatcherDataCache dataCache_; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_FILE_WATCHER_H diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_watch_entity.h b/interfaces/kits/js/src/mod_fs/class_watcher/fs_watch_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..88fe92b1869b6288404a0365d0e2be108325bd37 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_watch_entity.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_WATCHER_FS_WATCH_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_WATCH_ENTITY_H + +#include +#include +#include +#include "i_watcher_callback.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +struct WatchEvent { + std::string fileName = ""; + uint32_t event = 0; + uint32_t cookie = 0; +}; + +struct WatcherInfo { + std::string fileName = ""; + uint32_t events = 0; + int32_t wd = -1; + std::shared_ptr callback; + + explicit WatcherInfo(std::shared_ptr callback) : callback(std::move(callback)) {} + + void TriggerCallback(const std::string &fileName, uint32_t event, uint32_t cookie) const + { + callback->InvokeCallback(fileName, event, cookie); + } +}; + +struct FsWatchEntity { + std::shared_ptr data_; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_WATCH_ENTITY_H diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_watcher.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/fs_watcher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6be59006599de21006b235eb93efcb7932ba47b9 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_watcher.cpp @@ -0,0 +1,78 @@ +/* + * 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_watcher.h" + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_file_watcher.h" +#include "fs_watch_entity.h" +#include "securec.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +FsResult FsWatcher::Constructor() +{ + auto watchEntity = CreateUniquePtr(); + if (watchEntity == nullptr) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + + FsWatcher *watcherPtr = new FsWatcher(move(watchEntity)); + + if (watcherPtr == nullptr) { + HILOGE("Failed to create FsWatcher object on heap."); + return FsResult::Error(ENOMEM); + } + + return FsResult::Success(move(watcherPtr)); +} + +FsResult FsWatcher::Stop() +{ + if (!watchEntity) { + HILOGE("Failed to get watchEntity when stop."); + return FsResult::Error(EINVAL); + } + int ret = FsFileWatcher::GetInstance().StopNotify(watchEntity->data_); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to stopNotify errno:%{public}d", errno); + return FsResult::Error(ret); + } + return FsResult::Success(); +} + +FsResult FsWatcher::Start() +{ + if (!watchEntity) { + HILOGE("Failed to get watchEntity when start."); + return FsResult::Error(EINVAL); + } + + shared_ptr info = watchEntity->data_; + int ret = FsFileWatcher::GetInstance().StartNotify(info); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to startNotify."); + return FsResult::Error(ret); + } + + FsFileWatcher::GetInstance().AsyncGetNotifyEvent(); + + return FsResult::Success(); +} + +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/fs_watcher.h b/interfaces/kits/js/src/mod_fs/class_watcher/fs_watcher.h new file mode 100644 index 0000000000000000000000000000000000000000..46a1c5340b5c249e7c62b54bc95196bca1188003 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/fs_watcher.h @@ -0,0 +1,48 @@ +/* + * 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_FS_WATCHER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_WATCHER_H + +#include "filemgmt_libfs.h" +#include "fs_watch_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +class FsWatcher { +public: + static FsResult Constructor(); + FsResult Start(); + FsResult Stop(); + + FsWatchEntity *GetWatchEntity() const + { + return watchEntity.get(); + } + + FsWatcher(const FsWatcher &) = delete; + FsWatcher &operator=(const FsWatcher &) = delete; + + FsWatcher(FsWatcher &&) noexcept = default; + FsWatcher &operator=(FsWatcher &&) noexcept = default; + + ~FsWatcher() = default; + +private: + unique_ptr watchEntity; + explicit FsWatcher(unique_ptr entity) : watchEntity(move(entity)) {} +}; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_FS_WATCHER_H diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/i_watcher_callback.h b/interfaces/kits/js/src/mod_fs/class_watcher/i_watcher_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..a6baaa78226de612f9a3eb321b823887b02cd4eb --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/class_watcher/i_watcher_callback.h @@ -0,0 +1,32 @@ +/* + * 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_I_WATCHER_CALLBACK_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_I_WATCHER_CALLBACK_H + +#include + +namespace OHOS::FileManagement::ModuleFileIO { + +class IWatcherCallback { +public: + virtual ~IWatcherCallback() = default; + virtual bool IsStrictEquals(const std::shared_ptr &other) const = 0; + virtual void InvokeCallback(const std::string &fileName, uint32_t event, uint32_t cookie) const = 0; + virtual std::string GetClassName() const = 0; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_CLASS_WATCHER_I_WATCHER_CALLBACK_H \ No newline at end of file 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 0000000000000000000000000000000000000000..83b5e2a51d734de7f54b020ef54e0bbffa608ae0 --- /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 0000000000000000000000000000000000000000..e18d584f1ce7dc0c7814157e638e240724599d81 --- /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/ani/connectdfs_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/connectdfs_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da3f63b52fc23add8144ca97b4d47a55d0efa873 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/connectdfs_ani.cpp @@ -0,0 +1,95 @@ +/* + * 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 "connectdfs_ani.h" +#include "connectdfs_core.h" +#include "filemgmt_libhilog.h" +#include "error_handler.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +using namespace std; +void ConnectDfsAni::ConnectDfsSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string networkId, + ani_object listener) +{ + //注册 + auto [succNetworkId, networkIdStr] = TypeConverter::ToUTF8String(env, networkId); + if (!succNetworkId) { + HILOGE("Invalid NetworkId"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + sptr anidfslistener_(new(std::nothrow) ANIDfsListener()); + anidfslistener_->SetConnectDfsEnv(env); + ani_ref promiseDeferred = nullptr; + + if (listener != nullptr) { + anidfslistener_->SetConnectDfsCBRef(listener); + HILOGE("Connectdfs set callback success"); + } else { + anidfslistener_->SetConnectDfsPromiseRef(promiseDeferred); + HILOGE("Connectdfs set Promise success"); + } + + auto ret = ConnectDfsCore::ConnectDfsExec(networkIdStr, anidfslistener_); + if (!ret.IsSuccess()) { + HILOGE("ConnectDfsExec failed"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } +} + +void ANIDfsListener::SetConnectDfsEnv(ani_env *env) +{ + env_ = env; +} + +void ANIDfsListener::SetConnectDfsCBRef(ani_ref ref) +{ + onStatusRef_ = ref; +} + +void ANIDfsListener::SetConnectDfsPromiseRef(ani_ref promiseDeferred) +{ + promiseDeferred_ = promiseDeferred; +} + +void ANIDfsListener::OnStatus(const std::string &networkId, int32_t status) +{ + //回调 + ani_string networkId_; + ani_status res = env_->String_NewUTF8(networkId.c_str(), networkId.size(), &networkId_); + if (res != ANI_OK) { + HILOGE("std string to ani string failed. ret = %{public}d", static_cast(res)); + ErrorHandler::Throw(env_, E_PARAMS); + return; + } + ani_double status_ = static_cast(status); + ani_status ret = env_->Object_CallMethodByName_Void(static_cast(objectlistener), "onStatus", nullptr, + networkId_, status_); + if (ret != ANI_OK) { + HILOGE("Object_CallMethodByName_Void failed. ret = %{public}d", static_cast(ret)); + ErrorHandler::Throw(env_, E_PARAMS); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/connectdfs_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/connectdfs_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..b215b37aa4599c76507767ddb954a2d6e87825d6 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/connectdfs_ani.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_PROPERTIES_ANI_CONNECTDFS_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_CONNECTDFS_ANI_H + +#include +#include +#include "dfs_listener/file_dfs_listener_stub.h" +#include "distributed_file_daemon_manager.h" +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; + +class ANIDfsListener : public FileDfsListenerStub { +public: + void OnStatus(const std::string &networkId, int32_t status); + void SetConnectDfsEnv(ani_env *env); + void SetConnectDfsCBRef(ani_ref ref); + void SetConnectDfsPromiseRef(ani_ref promiseDeferred); + +private: + ani_env *env_ = nullptr; + ani_ref onStatusRef_ = nullptr; + ani_ref promiseDeferred_ = nullptr; + ani_ref objectlistener = nullptr; +}; +class ConnectDfsAni final { +public: + static void ConnectDfsSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string networkId, + ani_object listener); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_CONNECTDFS_ANI_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 new file mode 100644 index 0000000000000000000000000000000000000000..541cd7f6c36b055ba7f46ca5ef25f2535a66bb98 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp @@ -0,0 +1,170 @@ +/* + * 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_ani.h" + +#include "ani_helper.h" +#include "ani_signature.h" +#include "copy_core.h" +#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 { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +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.progressListener = move(listener); + return true; +} + +static bool ParseCopySignalFromOptionArg(ani_env *env, const ani_object &options, CopyOptions &opts) +{ + 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; + } + + 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; + } + + 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_object &options) +{ + ani_boolean isUndefined; + env->Reference_IsUndefined(options, &isUndefined); + if (isUndefined) { + return { true, nullopt }; + } + + CopyOptions opts; + auto succ = ParseListenerFromOptionArg(env, options, opts); + if (!succ) { + return { false, nullopt }; + } + + succ = ParseCopySignalFromOptionArg(env, options, opts); + if (!succ) { + return { false, nullopt }; + } + + return { true, make_optional(move(opts)) }; +} + +void CopyAni::CopySync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string srcUri, ani_string destUri, ani_object options) +{ + auto [succSrc, src] = TypeConverter::ToUTF8String(env, srcUri); + auto [succDest, dest] = TypeConverter::ToUTF8String(env, destUri); + auto [succOpts, opts] = ParseOptions(env, options); + + 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; + } + + auto ret = CopyCore::DoCopy(src, dest, opts); + if (!ret.IsSuccess()) { + HILOGE("DoCopy failed!"); + const FsError &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..fbbcf9d08f1ed635028dd993e03f7bddfd36f00e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +class CopyAni final { +public: + static void CopySync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string srcUri, ani_string destUri, ani_object options); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..13804c8ad3d433a93a3ca1589bd387e7fd3010bf --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.cpp @@ -0,0 +1,165 @@ +/* + * 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_dir_ani.h" + +#include +#include "ani_signature.h" +#include "copy_dir_core.h" +#include "error_handler.h" +#include "filemgmt_libhilog.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; + +static tuple ToConflictFiles(ani_env *env, const ConflictFiles &files) +{ + auto classDesc = FS::ConflictFilesInner::classDesc.c_str(); + ani_class cls; + ani_status ret; + if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { + HILOGE("Cannot find class %{private}s, err: %{private}d", classDesc, ret); + return { false, nullptr }; + } + + auto ctorDesc = FS::ConflictFilesInner::ctorDesc.c_str(); + auto ctorSig = FS::ConflictFilesInner::ctorSig.c_str(); + ani_method ctor; + if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { + HILOGE("Cannot find class %{private}s constructor method, err: %{private}d", classDesc, ret); + return { false, nullptr }; + } + + auto [succSrc, src] = TypeConverter::ToAniString(env, files.srcFiles); + if (!succSrc) { + HILOGE("Convert ConflictFiles srcFiles to ani string failed!"); + return { false, nullptr }; + } + + auto [succDest, dest] = TypeConverter::ToAniString(env, files.destFiles); + if (!succSrc) { + HILOGE("Convert ConflictFiles destFiles to ani string failed!"); + return { false, nullptr }; + } + + ani_object obj; + if ((ret = env->Object_New(cls, ctor, &obj, src, dest)) != ANI_OK) { + HILOGE("Create ConflictFiles object failed!, err: %{private}d", ret); + return { false, nullptr }; + } + + return { true, obj }; +} + +static tuple> ToConflictFilesArray( + ani_env *env, const optional> &errFiles) +{ + if (!errFiles.has_value()) { + return { true, nullopt }; + } + auto classDesc = BuiltInTypes::Array::classDesc.c_str(); + ani_class cls = nullptr; + ani_status ret; + + if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { + HILOGE("Cannot find class %{private}s, err: %{private}d", classDesc, ret); + return { false, nullopt }; + } + + auto ctorDesc = BuiltInTypes::Array::ctorDesc.c_str(); + auto ctorSig = BuiltInTypes::Array::ctorSig.c_str(); + ani_method ctor; + if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { + HILOGE("Cannot find class %{private}s constructor method, err: %{private}d", classDesc, ret); + return { false, nullopt }; + } + + ani_object arr; + auto files = errFiles.value(); + if ((ret = env->Object_New(cls, ctor, &arr, files.size())) != ANI_OK) { + HILOGE("Create Array failed!, err: %{private}d", ret); + return { false, nullopt }; + } + + auto setterDesc = BuiltInTypes::Array::setterDesc.c_str(); + auto setterSig = BuiltInTypes::Array::objectSetterSig.c_str(); + ani_size index = 0; + for (const auto &errFile : files) { + auto [succ, fileObj] = ToConflictFiles(env, errFile); + if (!succ) { + return { false, nullopt }; + } + + if ((ret = env->Object_CallMethodByName_Void(arr, setterDesc, setterSig, index, fileObj)) != ANI_OK) { + HILOGE("Add element to Array failed, err: %{private}d", ret); + return { false, nullopt }; + } + index++; + } + + return { true, make_optional(move(arr)) }; +} + +void CopyDirAni::CopyDirSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string src, ani_string dest, ani_object mode) +{ + error_code errCode; + + auto [succSrc, srcPath] = TypeConverter::ToUTF8String(env, src); + if (!succSrc) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [succDest, destPath] = TypeConverter::ToUTF8String(env, dest); + if (!succDest) { + HILOGE("Invalid dest, errCode = %{public}d", errCode.value()); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [succMode, optMode] = TypeConverter::ToOptionalInt32(env, mode); + if (!succMode) { + HILOGE("Invalid mode"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [fsResult, errFiles] = CopyDirCore::DoCopyDir(srcPath, destPath, optMode); + if (!fsResult.IsSuccess()) { + HILOGE("DoCopyFile failed!"); + auto [succ, errData] = ToConflictFilesArray(env, errFiles); + if (!succ) { + HILOGE("Convert conflict files array failed"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return; + } + const FsError &err = fsResult.GetError(); + ErrorHandler::Throw(env, err, errData); + return; + } +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..469b5fe414a01499ffd620f73057772ad3be80ea --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_DIR_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_DIR_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +class CopyDirAni final { +public: + static void CopyDirSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string src, ani_string dest, ani_object mode); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_DIR_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/disconnectdfs_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/disconnectdfs_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7beafaeaaf27a429c70c695899865b3da4fc0f7d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/disconnectdfs_ani.cpp @@ -0,0 +1,46 @@ +/* + * 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 "disconnectdfs_ani.h" +#include "disconnectdfs_core.h" +#include "filemgmt_libhilog.h" +#include "error_handler.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +using namespace std; +void DisConnectDfsAni::DisConnectDfsSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string networkId) +{ + auto [succNetworkId, networkIdStr] = TypeConverter::ToUTF8String(env, networkId); + if (!succNetworkId) { + HILOGE("Invalid NetworkId"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + auto ret = DisConnectDfsCore::DisConnectDfsExec(networkIdStr); + if (!ret.IsSuccess()) { + HILOGE("DisConnectDfsExec failed"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/disconnectdfs_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/disconnectdfs_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..a42dab9cc026ee54cb102e614cd6c86863423794 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/disconnectdfs_ani.h @@ -0,0 +1,38 @@ +/* + * 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_ANI_DISCONNECTDFS_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_DISCONNECTDFS_ANI_H + +#include +#include "dfs_listener/file_dfs_listener_stub.h" +#include "distributed_file_daemon_manager.h" +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class DisConnectDfsAni final { +public: + static void DisConnectDfsSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string networkId); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_DISCONNECTDFS_ANI_H diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/fdatasync_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/fdatasync_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ce4a8bfc81fd4fb130d5819365ba492ab186f3f --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/fdatasync_ani.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fdatasync_ani.h" + +#include + +#include "error_handler.h" +#include "fdatasync_core.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +void FDataSyncAni::FDataSyncSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd) +{ + auto ret = FDataSyncCore::DoFDataSync(static_cast(fd)); + if (!ret.IsSuccess()) { + HILOGE("Fdatasync failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/fdatasync_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/fdatasync_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..ce0b8326125c526b1fc78de7bb0aaba22c67aa71 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/fdatasync_ani.h @@ -0,0 +1,36 @@ +/* + * 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_ANI_FDATASYNC_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_FDATASYNC_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class FDataSyncAni final { +public: + static void FDataSyncSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_FDATASYNC_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/fdopen_stream_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/fdopen_stream_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc6e8d27415910d8118119f59264400d58283398 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/fdopen_stream_ani.cpp @@ -0,0 +1,62 @@ +/* + * 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 "fdopen_stream_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "fdopen_stream_core.h" +#include "stream_wrapper.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; + +ani_object FdopenStreamAni::FdopenStreamSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd, ani_string mode) +{ + auto [succMode, openMode] = TypeConverter::ToUTF8String(env, mode); + if (!succMode) { + HILOGE("Invalid mode"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + FsResult ret = FdopenStreamCore::DoFdopenStream(static_cast(fd), openMode); + if (!ret.IsSuccess()) { + HILOGE("fdopen stream failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + + const FsStream *stream = ret.GetData().value(); + auto result = StreamWrapper::Wrap(env, move(stream)); + if (result == nullptr) { + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/fdopen_stream_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/fdopen_stream_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..81f0fde31b630e1e90a6243ba335cd8b5c254215 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/fdopen_stream_ani.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +class FdopenStreamAni final { +public: + static ani_object FdopenStreamSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd, ani_string mode); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/fsync_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/fsync_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f2680914fc313466b722d22ffbe162118d603b6f --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/fsync_ani.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 "fsync_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "fsync_core.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO; + +void FsyncAni::FsyncSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd) +{ + auto ret = FsyncCore::DoFsync(static_cast(fd)); + if (!ret.IsSuccess()) { + HILOGE("DoFsync failed!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/fsync_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/fsync_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..ad9d936fe9c5a6cb1b6bf1a536a91d99bc599642 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/fsync_ani.h @@ -0,0 +1,35 @@ +/* + * 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_ANI_FSYNC_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_FSYNC_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class FsyncAni final { +public: + static void FsyncSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_FSYNC_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/listfile_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/listfile_ani.cpp index 6b65ec5ce49d8283d013b6cd76245bb157abb0dd..8016f4f6c7acfe61a4e3c9b840009753c8656a4c 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/listfile_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/listfile_ani.cpp @@ -65,7 +65,7 @@ tuple ParseIntParam(ani_env *env, ani_object obj, string tag) } ani_int resultRefRes; if (ANI_OK != env->Object_CallMethodByName_Int( - static_cast(resultRef), "intValue", nullptr, &resultRefRes)) { + static_cast(resultRef), "toInt", nullptr, &resultRefRes)) { result = -1; return { false, result }; } diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/lseek_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/lseek_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d689c696ff61f52234c577d46c741d24b5753c0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/lseek_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 "lseek_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "lseek_core.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; + +optional ParseSeekPos(const optional &whence) +{ + if (!whence.has_value()) { + return nullopt; + } + + return make_optional(static_cast(move(whence.value()))); +} + +ani_double LseekAni::LseekSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd, ani_double offset, ani_enum_item whence) +{ + auto [succWhence, whenceOp] = TypeConverter::EnumToInt32(env, whence); + if (!succWhence) { + HILOGE("Invalid whence"); + ErrorHandler::Throw(env, EINVAL); + return -1; + } + auto pos = ParseSeekPos(whenceOp); + + auto ret = LseekCore::DoLseek(static_cast(fd), static_cast(offset), pos); + if (!ret.IsSuccess()) { + HILOGE("DoLseek failed!"); + const FsError &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return -1; + } + + return ani_double(static_cast(ret.GetData().value())); +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/lseek_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/lseek_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..5a7995d799ec2ab6d000304f4b4a1d9589a58177 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/lseek_ani.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_LSEEK_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_LSEEK_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +class LseekAni final { +public: + static ani_double LseekSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_double fd, ani_double offset, ani_enum_item whence); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_LSEEK_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/mkdtemp_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/mkdtemp_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42b5a73167eca8dcf6782f61016dea3d1ee24f26 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/mkdtemp_ani.cpp @@ -0,0 +1,60 @@ +/* + * 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 "mkdtemp_ani.h" + +#include + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "mkdtemp_core.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +ani_string MkdtempAni::MkdtempSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string prefix) +{ + auto [succPath, prefixPath] = TypeConverter::ToUTF8String(env, prefix); + if (!succPath) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto ret = MkdtempCore::DoMkdtemp(prefixPath); + if (!ret.IsSuccess()) { + HILOGE("Mkdtemp faild"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + + const auto &res = ret.GetData().value(); + auto [succ, result] = TypeConverter::ToAniString(env, res); + if (!succ) { + HILOGE("Create ani_string error"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/mkdtemp_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/mkdtemp_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..cda9c8e12905bb44cf86f03a70dc57ce369deed4 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/mkdtemp_ani.h @@ -0,0 +1,36 @@ +/* + * 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_ANI_MKDTEMP_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_MKDTEMP_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class MkdtempAni final { +public: + static ani_string MkdtempSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string prefix); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_MKDTEMP_ANI_H diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/movedir_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/movedir_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77633e1b5267a2026da780686522c2f879505867 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/movedir_ani.cpp @@ -0,0 +1,155 @@ +/* + * 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 "movedir_ani.h" + +#include +#include "ani_signature.h" +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "movedir_core.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +static tuple ToConflictFiles(ani_env *env, const ErrFiles &files) +{ + auto classDesc = FS::ConflictFilesInner::classDesc.c_str(); + ani_class cls; + ani_status ret; + if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { + HILOGE("Cannot find class %{private}s, err: %{private}d", classDesc, ret); + return { false, nullptr }; + } + + auto ctorDesc = FS::ConflictFilesInner::ctorDesc.c_str(); + auto ctorSig = FS::ConflictFilesInner::ctorSig.c_str(); + ani_method ctor; + if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { + HILOGE("Cannot find class %{private}s constructor method, err: %{private}d", classDesc, ret); + return { false, nullptr }; + } + + auto [succSrc, src] = TypeConverter::ToAniString(env, files.srcFiles); + if (!succSrc) { + HILOGE("Convert ConflictFiles srcFiles to ani string failed!"); + return { false, nullptr }; + } + + auto [succDest, dest] = TypeConverter::ToAniString(env, files.destFiles); + if (!succSrc) { + HILOGE("Convert ConflictFiles destFiles to ani string failed!"); + return { false, nullptr }; + } + + ani_object obj; + if ((ret = env->Object_New(cls, ctor, &obj, src, dest)) != ANI_OK) { + HILOGE("Create ConflictFiles object failed!, err: %{private}d", ret); + return { false, nullptr }; + } + + return { true, obj }; +} + +static tuple> ToConflictFilesArray( + ani_env *env, const optional> &errFiles) +{ + if (!errFiles.has_value()) { + return { true, nullopt }; + } + auto classDesc = BuiltInTypes::Array::classDesc.c_str(); + ani_class cls = nullptr; + ani_status ret; + + if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { + HILOGE("Cannot find class %{private}s, err: %{private}d", classDesc, ret); + return { false, nullopt }; + } + + auto ctorDesc = BuiltInTypes::Array::ctorDesc.c_str(); + auto ctorSig = BuiltInTypes::Array::ctorSig.c_str(); + ani_method ctor; + if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { + HILOGE("Cannot find class %{private}s constructor method, err: %{private}d", classDesc, ret); + return { false, nullopt }; + } + + ani_object arr; + auto files = errFiles.value(); + if ((ret = env->Object_New(cls, ctor, &arr, files.size())) != ANI_OK) { + HILOGE("Create Array failed!, err: %{private}d", ret); + return { false, nullopt }; + } + + auto setterDesc = BuiltInTypes::Array::setterDesc.c_str(); + auto setterSig = BuiltInTypes::Array::objectSetterSig.c_str(); + ani_size index = 0; + for (const auto &errFile : files) { + auto [succ, fileObj] = ToConflictFiles(env, errFile); + if (!succ) { + return { false, nullopt }; + } + + if ((ret = env->Object_CallMethodByName_Void(arr, setterDesc, setterSig, index, fileObj)) != ANI_OK) { + HILOGE("Add element to Array failed, err: %{private}d", ret); + return { false, nullopt }; + } + index++; + } + + return { true, make_optional(move(arr)) }; +} + +void MoveDirAni::MoveDirSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string src, ani_string dest, ani_object mode) +{ + auto [succSrc, srcPath] = TypeConverter::ToUTF8String(env, src); + auto [succDest, destPath] = TypeConverter::ToUTF8String(env, dest); + if (!succSrc || !succDest) { + HILOGE("The first/second argument requires filepath"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [succMode, optMode] = TypeConverter::ToOptionalInt32(env, mode); + if (!succMode) { + HILOGE("Invalid mode"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [fsResult, errFiles] = MoveDirCore::DoMoveDir(srcPath, destPath, optMode); + if (!fsResult.IsSuccess()) { + HILOGE("DoMoveDir failed!"); + auto [succ, errData] = ToConflictFilesArray(env, errFiles); + if (!succ) { + HILOGE("Convert conflict files array failed"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return; + } + const FsError &err = fsResult.GetError(); + ErrorHandler::Throw(env, err, errData); + return; + } +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/movedir_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/movedir_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..bd17504464739b6b56f293980792b1e72b05d858 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/movedir_ani.h @@ -0,0 +1,36 @@ +/* + * 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_ANI_MOVEDIR_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_MOVEDIR_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class MoveDirAni final { +public: + static void MoveDirSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string src, ani_string dest, ani_object mode); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_MOVEDIR_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/symlink_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/symlink_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4cbac513388e666d58b321a6ab77e971b7dc279e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/symlink_ani.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "symlink_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "symlink_core.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +void SymlinkAni::SymlinkSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string target, ani_string srcPath) +{ + auto [succTarget, targetPath] = TypeConverter::ToUTF8String(env, target); + if (!succTarget) { + HILOGE("Invalid target"); + ErrorHandler::Throw(env, EINVAL); + return; + } + auto [succSrc, src] = TypeConverter::ToUTF8String(env, srcPath); + if (!succSrc) { + HILOGE("Invalid src"); + ErrorHandler::Throw(env, EINVAL); + return; + } + auto ret = SymlinkCore::DoSymlink(targetPath, src); + if (!ret.IsSuccess()) { + HILOGE("DoSymlink failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/symlink_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/symlink_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..6ba3abb554ecd244031623959486bcc81f45ea04 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/symlink_ani.h @@ -0,0 +1,35 @@ +/* + * 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_SYMLINK_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_SYMLINK_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class SymlinkAni final { +public: + static void SymlinkSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string target, ani_string srcPath); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_SYMLINK_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/utimes_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/utimes_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..849f10d4d789b07971c92d3f5ac422d073f8642a --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/utimes_ani.cpp @@ -0,0 +1,48 @@ +/* + * 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 "utimes_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" +#include "utimes_core.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +void UtimesAni::Utimes( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_double mtime) +{ + auto [succPath, newPath] = TypeConverter::ToUTF8String(env, path); + if (!succPath) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return; + } + auto ret = UtimesCore::DoUtimes(newPath, static_cast(mtime)); + if (!ret.IsSuccess()) { + HILOGE("Utimes failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/utimes_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/utimes_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..118f7d25ad1cd1fb7cc4442f4e4826af311a36f4 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/utimes_ani.h @@ -0,0 +1,36 @@ +/* + * 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_UTIMES_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_UTIMES_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class UtimesAni final { +public: + static void Utimes( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_double mtime); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_UTIMES_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/watcher_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/watcher_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f0641c93f26ae01b8445ad23e2947e524c9c3110 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/watcher_ani.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 "watcher_ani.h" + +#include "ani_helper.h" +#include "error_handler.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_watcher_wrapper.h" +#include "watch_event_listener.h" +#include "watcher_core.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace OHOS::FileManagement::ModuleFileIO; + +ani_object WatcherAni::CreateWatcherSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_double events, ani_ref listener) +{ + auto [succPath, filePath] = TypeConverter::ToUTF8String(env, path); + if (!succPath) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + ani_ref cbRef; + if (ANI_OK != env->GlobalReference_Create(move(listener), &cbRef)) { + HILOGE("Failed to get callback"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + ani_vm *vm = nullptr; + env->GetVM(&vm); + auto eventListener = CreateSharedPtr(vm, cbRef); + if (eventListener == nullptr) { + HILOGE("Failed to request heap memory."); + ErrorHandler::Throw(env, ENOMEM); + return nullptr; + } + + FsResult ret = + WatcherCore::DoCreateWatcher(filePath, static_cast(events), move(eventListener)); + if (!ret.IsSuccess()) { + HILOGE("Create watcher failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + const FsWatcher *watcher = ret.GetData().value(); + auto result = FsWatcherWrapper::Wrap(env, move(watcher)); + if (result == nullptr) { + delete watcher; + watcher = nullptr; + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/watcher_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/watcher_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..1175c2f6f67878a72c323ffbad99c9594b2e1682 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/watcher_ani.h @@ -0,0 +1,36 @@ +/* + * 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_WATCHER_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_WATCHER_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class WatcherAni final { +public: + static ani_object CreateWatcherSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_double events, ani_ref listener); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_WATCHER_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/write_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/write_ani.cpp index 64c8d1bfaccecc0dfcbae9034a136eac7fa673f9..a9a798a47348677fe77a59e44a1b459826c66f91 100644 --- a/interfaces/kits/js/src/mod_fs/properties/ani/write_ani.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/ani/write_ani.cpp @@ -40,13 +40,6 @@ static tuple> ToWriteOptions(ani_env *env, ani_obje return { true, nullopt }; } - auto [succEncoding, encoding] = AniHelper::ParseEncoding(env, obj); - if (!succEncoding) { - HILOGE("Illegal option.encoding parameter"); - return { false, nullopt }; - } - options.encoding = encoding; - auto [succOffset, offset] = AniHelper::ParseInt64Option(env, obj, "offset"); if (!succOffset) { HILOGE("Illegal option.offset parameter"); @@ -61,6 +54,12 @@ static tuple> ToWriteOptions(ani_env *env, ani_obje } options.length = length; + auto [succEncoding, encoding] = AniHelper::ParseEncoding(env, obj); + if (!succEncoding) { + HILOGE("Illegal option.encoding parameter"); + return { false, nullopt }; + } + options.encoding = encoding; return { true, make_optional(move(options)) }; } diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a69e0bd2eec613648097dd54ae5ff88e71b276c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.cpp @@ -0,0 +1,98 @@ +/* + * 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 "xattr_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" +#include "xattr_core.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +void XattrAni::SetXattrSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key, ani_string value) +{ + auto [pathSucc, pathStr] = TypeConverter::ToUTF8String(env, path); + if (!pathSucc) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [keySucc, keyStr] = TypeConverter::ToUTF8String(env, key); + if (!keySucc) { + HILOGE("Invalid xattr key"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [valueSucc, valueStr] = TypeConverter::ToUTF8String(env, value); + if (!valueSucc) { + HILOGE("Invalid xattr value"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto ret = XattrCore::DoSetXattr(pathStr, keyStr, valueStr); + if (!ret.IsSuccess()) { + HILOGE("DoSetXattr failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} + +ani_string XattrAni::GetXattrSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key) +{ + auto [pathSucc, pathStr] = TypeConverter::ToUTF8String(env, path); + if (!pathSucc) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto [keySucc, keyStr] = TypeConverter::ToUTF8String(env, key); + if (!keySucc) { + HILOGE("Invalid xattr key"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto ret = XattrCore::DoGetXattr(pathStr, keyStr); + if (!ret.IsSuccess()) { + HILOGE("DoSetXattr failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + + const auto &res = ret.GetData().value(); + auto [succ, result] = TypeConverter::ToAniString(env, res); + if (!succ) { + HILOGE("Create ani_string error"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..2bc788d12e55bf19e29f8a2b4ca9a541a4b70e1e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.h @@ -0,0 +1,38 @@ +/* + * 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_ANI_XATTR_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_XATTR_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class XattrAni final { +public: + static void SetXattrSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key, ani_string value); + static ani_string GetXattrSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_XATTR_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/connectdfs_core.cpp b/interfaces/kits/js/src/mod_fs/properties/connectdfs_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..999a460b83a848d81acdff48abae8b3c9b7d8a0c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/connectdfs_core.cpp @@ -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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "filemgmt_libhilog.h" +#include "distributed_file_daemon_manager.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace fs = std::filesystem; + +FsResult ConnectDfsCore::ConnectDfsExec(const std::string &networkId, sptr listener) +{ + if (networkId == "" || listener == nullptr) { + return FsResult::Error(E_PARAMS); + } + + int result = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance(). + OpenP2PConnectionEx(networkId, listener); + if (result != ERRNO_NOERR) { + HILOGE("Fail to openp2pconnection"); + return FsResult::Error(result); + } + return FsResult::Success(); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/connectdfs_core.h b/interfaces/kits/js/src/mod_fs/properties/connectdfs_core.h new file mode 100644 index 0000000000000000000000000000000000000000..9e6d713bcb5181edafdb7cdec1b10f5a86e7b4fe --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/connectdfs_core.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_KITS_JS_SRC_MOD_FS_PROPERTIES_CONNECTDFS_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CONNECTDFS_CORE_H +#include +#include +#include +#include +#include "bundle_mgr_client_impl.h" +#include "dfs_listener/file_dfs_listener_stub.h" +#include "distributed_file_daemon_manager.h" +#include "filemgmt_libfs.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class ConnectDfsCore final { +public: + static FsResult ConnectDfsExec(const std::string &networkId, sptr listener); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CONNECTDFS_CORE_H + diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45403ca6d82752fcac6b36e2cf72b2f063305337 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.cpp @@ -0,0 +1,887 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "datashare_helper.h" +#include "file_uri.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_utils.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "ipc_skeleton.h" +#include "system_ability_definition.h" +#include "trans_listener_core.h" +#include "utils_log.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace AppFileService::ModuleFileUri; +namespace fs = std::filesystem; +const std::string FILE_PREFIX_NAME = "file://"; +const std::string NETWORK_PARA = "?networkid="; +const string PROCEDURE_COPY_NAME = "FileFSCopy"; +const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const std::string MEDIA = "media"; +const int SLEEP_TIME = 100000; +constexpr int DISMATCH = 0; +constexpr int MATCH = 1; +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::callbackMap_; + +static int OpenSrcFile(const string &srcPth, std::shared_ptr infos, int32_t &srcFd) +{ + Uri uri(infos->srcUri); + if (uri.GetAuthority() == MEDIA) { + std::shared_ptr dataShareHelper = nullptr; + sptr remote = new (std::nothrow) IRemoteStub(); + if (!remote) { + HILOGE("Failed to get remote object"); + return ENOMEM; + } + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + if (!dataShareHelper) { + HILOGE("Failed to connect to datashare"); + return E_PERMISSION; + } + 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; + } + } else { + srcFd = open(srcPth.c_str(), O_RDONLY); + if (srcFd < 0) { + HILOGE("Error opening src file descriptor. errno = %{public}d", errno); + return errno; + } + } + return ERRNO_NOERR; +} + +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 }; + if (sendFileReq == nullptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int64_t offset = 0; + 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; + } + 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); + 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)) { + return ECANCELED; + } + } + offset += static_cast(ret); + size -= static_cast(ret); + if (ret == 0) { + break; + } + } + if (size != 0) { + HILOGE("The execution of the sendfile task was terminated, remaining file size %{public}" PRIu64, size); + return EIO; + } + return ERRNO_NOERR; +} + +bool CopyCore::IsValidUri(const std::string &uri) +{ + return uri.find(FILE_PREFIX_NAME) == 0; +} + +bool CopyCore::ValidOperand(std::string uriStr) +{ + return IsValidUri(uriStr); +} + +bool CopyCore::IsRemoteUri(const std::string &uri) +{ + // NETWORK_PARA + return uri.find(NETWORK_PARA) != uri.npos; +} + +bool CopyCore::IsDirectory(const std::string &path) +{ + struct stat buf {}; + int ret = stat(path.c_str(), &buf); + if (ret == -1) { + HILOGE("stat failed, errno is %{public}d", errno); + return false; + } + return (buf.st_mode & S_IFMT) == S_IFDIR; +} + +bool CopyCore::IsFile(const std::string &path) +{ + struct stat buf {}; + int ret = stat(path.c_str(), &buf); + if (ret == -1) { + HILOGI("stat failed, errno is %{public}d, ", errno); + return false; + } + return (buf.st_mode & S_IFMT) == S_IFREG; +} + +bool CopyCore::IsMediaUri(const std::string &uriPath) +{ + Uri uri(uriPath); + string bundleName = uri.GetAuthority(); + return bundleName == MEDIA; +} + +tuple CopyCore::GetFileSize(const std::string &path) +{ + struct stat buf {}; + int ret = stat(path.c_str(), &buf); + if (ret == -1) { + HILOGI("Stat failed."); + return { errno, 0 }; + } + return { ERRNO_NOERR, buf.st_size }; +} + +int CopyCore::CheckOrCreatePath(const std::string &destPath) +{ + std::error_code errCode; + if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { + HILOGI("destPath not exist"); + auto file = open(destPath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (file < 0) { + HILOGE("Error opening file descriptor. errno = %{public}d", errno); + return errno; + } + close(file); + } else if (errCode.value() != 0) { + return errCode.value(); + } + return ERRNO_NOERR; +} + +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; + int32_t ret = OpenSrcFile(src, infos, srcFd); + if (srcFd < 0) { + return ret; + } + auto destFd = open(dest.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (destFd < 0) { + HILOGE("Error opening dest file descriptor. errno = %{public}d", errno); + close(srcFd); + return errno; + } + auto srcFdg = CreateUniquePtr(srcFd, true); + auto destFdg = CreateUniquePtr(destFd, true); + if (srcFdg == nullptr || destFdg == nullptr) { + HILOGE("Failed to request heap memory."); + close(srcFd); + close(destFd); + return ENOMEM; + } + return SendFileCore(move(srcFdg), move(destFdg), infos); +} + +int CopyCore::MakeDir(const string &path) +{ + filesystem::path destDir(path); + std::error_code errCode; + if (!filesystem::create_directory(destDir, errCode)) { + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +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) { + int res = MakeDir(destPath); + if (res != ERRNO_NOERR) { + HILOGE("Failed to mkdir"); + return res; + } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + uint32_t watchEvents = IN_MODIFY; + if (infos->notifyFd >= 0) { + int newWd = inotify_add_watch(infos->notifyFd, destPath.c_str(), watchEvents); + if (newWd < 0) { + HILOGE("inotify_add_watch, newWd is unvaild, newWd = %{public}d", newWd); + return errno; + } + { + std::lock_guard lock(CopyCore::mutex_); + 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::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; + } + iter->second->wds.push_back({ newWd, receiveInfo }); + } + } + return RecurCopyDir(srcPath, destPath, infos); +} + +static int FilterFunc(const struct dirent *filename) +{ + if (string_view(filename->d_name) == "." || string_view(filename->d_name) == "..") { + return DISMATCH; + } + return MATCH; +} + +struct NameList { + struct dirent **namelist = { nullptr }; + int direntNum = 0; +}; + +static void Deleter(struct NameList *arg) +{ + for (int i = 0; i < arg->direntNum; i++) { + free((arg->namelist)[i]); + (arg->namelist)[i] = nullptr; + } + free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; +} + +std::string CopyCore::GetRealPath(const std::string &path) +{ + fs::path tempPath(path); + fs::path realPath {}; + for (const auto &component : tempPath) { + if (component == ".") { + continue; + } else if (component == "..") { + realPath = realPath.parent_path(); + } else { + realPath /= component; + } + } + return realPath.string(); +} + +uint64_t CopyCore::GetDirSize(std::shared_ptr infos, std::string path) +{ + unique_ptr pNameList = { new (nothrow) struct NameList, Deleter }; + if (pNameList == nullptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int num = scandir(path.c_str(), &(pNameList->namelist), FilterFunc, alphasort); + pNameList->direntNum = num; + + long int size = 0; + for (int i = 0; i < num; i++) { + string dest = path + '/' + string((pNameList->namelist[i])->d_name); + if ((pNameList->namelist[i])->d_type == DT_LNK) { + continue; + } + if ((pNameList->namelist[i])->d_type == DT_DIR) { + size += static_cast(GetDirSize(infos, dest)); + } else { + struct stat st {}; + if (stat(dest.c_str(), &st) == -1) { + return size; + } + size += st.st_size; + } + } + return size; +} + +int CopyCore::RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr infos) +{ + unique_ptr pNameList = { new (nothrow) struct NameList, Deleter }; + if (pNameList == nullptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int num = scandir(srcPath.c_str(), &(pNameList->namelist), FilterFunc, alphasort); + pNameList->direntNum = num; + + for (int i = 0; i < num; i++) { + string src = srcPath + '/' + string((pNameList->namelist[i])->d_name); + string dest = destPath + '/' + string((pNameList->namelist[i])->d_name); + if ((pNameList->namelist[i])->d_type == DT_LNK) { + continue; + } + int ret = ERRNO_NOERR; + if ((pNameList->namelist[i])->d_type == DT_DIR) { + ret = CopySubDir(src, dest, infos); + } else { + infos->filePaths.insert(dest); + ret = CopyFile(src, dest, infos); + } + if (ret != ERRNO_NOERR) { + return ret; + } + } + return ERRNO_NOERR; +} + +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()); + size_t found = dest.find(src); + if (found != std::string::npos && found == 0) { + return EINVAL; + } + fs::path srcPath = fs::u8path(src); + std::string dirName; + if (srcPath.has_parent_path()) { + dirName = srcPath.parent_path().filename(); + } + string destStr = dest + "/" + dirName; + return CopySubDir(src, destStr, infos); +} + +int CopyCore::ExecLocal(std::shared_ptr infos, std::shared_ptr callback) +{ + if (infos->isFile) { + if (infos->srcPath == infos->destPath) { + HILOGE("The src and dest is same"); + return EINVAL; + } + int ret = CheckOrCreatePath(infos->destPath); + if (ret != ERRNO_NOERR) { + HILOGE("check or create fail, error code is %{public}d", ret); + return ret; + } + } + if (!infos->hasListener) { + return ExecCopy(infos); + } + auto ret = SubscribeLocalListener(infos, callback); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to subscribe local listener, errno = %{public}d", ret); + return ret; + } + StartNotify(infos, callback); + return ExecCopy(infos); +} + +int CopyCore::SubscribeLocalListener(std::shared_ptr infos, std::shared_ptr callback) +{ + infos->notifyFd = inotify_init(); + if (infos->notifyFd < 0) { + HILOGE("Failed to init inotify, errno:%{public}d", errno); + return errno; + } + infos->eventFd = eventfd(0, EFD_CLOEXEC); + if (infos->eventFd < 0) { + HILOGE("Failed to init eventFd, errno:%{public}d", errno); + return errno; + } + callback->notifyFd = infos->notifyFd; + callback->eventFd = infos->eventFd; + int newWd = inotify_add_watch(infos->notifyFd, infos->destPath.c_str(), IN_MODIFY); + 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()); + CloseNotifyFdLocked(infos, callback); + return errCode; + } + auto receiveInfo = CreateSharedPtr(); + if (receiveInfo == nullptr) { + HILOGE("Failed to request heap memory."); + inotify_rm_watch(infos->notifyFd, newWd); + CloseNotifyFdLocked(infos, callback); + return ENOMEM; + } + receiveInfo->path = infos->destPath; + callback->wds.push_back({ newWd, receiveInfo }); + if (!infos->isFile) { + callback->totalSize = GetDirSize(infos, infos->srcPath); + return ERRNO_NOERR; + } + auto [err, fileSize] = GetFileSize(infos->srcPath); + if (err == ERRNO_NOERR) { + callback->totalSize = fileSize; + } + return err; +} + +std::shared_ptr CopyCore::RegisterListener(const std::shared_ptr &infos) +{ + auto callback = CreateSharedPtr(infos->listener); + if (callback == nullptr) { + HILOGE("Failed to request heap memory."); + return nullptr; + } + std::lock_guard lock(mutex_); + auto iter = callbackMap_.find(*infos); + if (iter != callbackMap_.end()) { + HILOGE("CopyCore::RegisterListener, already registered."); + return nullptr; + } + callbackMap_.insert({ *infos, callback }); + return callback; +} + +void CopyCore::UnregisterListener(std::shared_ptr fileInfos) +{ + if (fileInfos == nullptr) { + HILOGE("fileInfos is nullptr"); + return; + } + std::lock_guard lock(mutex_); + auto iter = callbackMap_.find(*fileInfos); + if (iter == callbackMap_.end()) { + HILOGI("It is not be registered."); + return; + } + callbackMap_.erase(*fileInfos); +} + +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) { + return; + } + entry->callback->maxProgressSize = processedSize; + auto listener = entry->callback->listener; + if (listener == nullptr) { + HILOGE("listener pointer is nullptr."); + return; + } + listener->InvokeListener(processedSize, entry->totalSize); +} + +FsUvEntry *CopyCore::GetUVEntry(std::shared_ptr infos) +{ + FsUvEntry *entry = nullptr; + { + std::lock_guard lock(mutex_); + auto iter = callbackMap_.find(*infos); + if (iter == callbackMap_.end()) { + HILOGE("Failed to find callback"); + return nullptr; + } + auto callback = iter->second; + entry = new (std::nothrow) FsUvEntry(iter->second, infos); + if (entry == nullptr) { + HILOGE("entry ptr is nullptr."); + return nullptr; + } + entry->progressSize = callback->progressSize; + entry->totalSize = callback->totalSize; + } + return entry; +} + +void CopyCore::OnFileReceive(std::shared_ptr infos) +{ + std::shared_ptr entry(GetUVEntry(infos)); + if (entry == nullptr) { + HILOGE("failed to get uv entry"); + return; + } + ReceiveComplete(entry); +} + +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; }); + if (it != callback->wds.end()) { + return it->second; + } + return nullptr; +} + +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) +{ + auto [err, fileSize] = GetFileSize(filePath); + if (err != ERRNO_NOERR) { + HILOGE("GetFileSize failed, err: %{public}d.", err); + return err; + } + auto size = fileSize; + auto iter = receivedInfo->fileList.find(filePath); + if (iter == receivedInfo->fileList.end()) { + receivedInfo->fileList.insert({ filePath, size }); + callback->progressSize += size; + } else { // file + if (size > iter->second) { + callback->progressSize += (size - iter->second); + iter->second = size; + } + } + return ERRNO_NOERR; +} + +std::shared_ptr CopyCore::GetRegisteredListener(std::shared_ptr infos) +{ + std::lock_guard lock(mutex_); + 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) +{ + callback->closed = false; + infos->eventFd = -1; + infos->notifyFd = -1; + { + std::unique_lock lock(callback->cvLock); + callback->CloseFd(); + callback->cv.notify_one(); + } +} + +void CopyCore::CloseNotifyFdLocked(std::shared_ptr infos, std::shared_ptr callback) +{ + { + lock_guard lock(callback->readMutex); + callback->closed = true; + if (callback->reading) { + HILOGE("close while reading"); + return; + } + } + CloseNotifyFd(infos, callback); +} + +tuple CopyCore::HandleProgress( + inotify_event *event, std::shared_ptr infos, std::shared_ptr callback) +{ + if (callback == nullptr) { + return { true, EINVAL, false }; + } + auto receivedInfo = GetReceivedInfo(event->wd, callback); + if (receivedInfo == nullptr) { + return { true, EINVAL, false }; + } + std::string fileName = receivedInfo->path; + if (!infos->isFile) { // files under subdir + fileName += "/" + string(event->name); + if (!CheckFileValid(fileName, infos)) { + return { true, EINVAL, false }; + } + auto err = UpdateProgressSize(fileName, receivedInfo, callback); + if (err != ERRNO_NOERR) { + return { false, err, false }; + } + } else { + auto [err, fileSize] = GetFileSize(fileName); + if (err != ERRNO_NOERR) { + return { false, err, false }; + } + callback->progressSize = fileSize; + } + return { true, callback->errorCode, true }; +} + +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 && index < len) { + event = reinterpret_cast(buf + index); + auto [needContinue, errCode, needSend] = HandleProgress(event, infos, callback); + if (!needContinue) { + infos->exceptionCode = errCode; + return; + } + if (needContinue && !needSend) { + index += static_cast(sizeof(struct inotify_event) + event->len); + continue; + } + if (!callback || (callback->progressSize == callback->totalSize)) { + infos->run = false; + return; + } + auto currentTime = std::chrono::steady_clock::now(); + if (currentTime >= infos->notifyTime) { + OnFileReceive(infos); + infos->notifyTime = currentTime + NOTIFY_PROGRESS_DELAY; + } + index += static_cast(sizeof(struct inotify_event) + event->len); + } +} + +void CopyCore::ReadNotifyEventLocked(std::shared_ptr infos, std::shared_ptr callback) +{ + { + std::lock_guard lock(callback->readMutex); + if (callback->closed) { + HILOGE("read after close"); + return; + } + callback->reading = true; + } + ReadNotifyEvent(infos); + { + std::lock_guard lock(callback->readMutex); + callback->reading = false; + if (callback->closed) { + HILOGE("close after read"); + CloseNotifyFd(infos, callback); + return; + } + } +} + +void CopyCore::GetNotifyEvent(std::shared_ptr infos) +{ + auto callback = GetRegisteredListener(infos); + if (callback == nullptr) { + infos->exceptionCode = EINVAL; + return; + } + prctl(PR_SET_NAME, "NotifyThread"); + nfds_t nfds = 2; + struct pollfd fds[2]; + fds[0].events = 0; + fds[1].events = POLLIN; + fds[0].fd = infos->eventFd; + fds[1].fd = infos->notifyFd; + while (infos->run && infos->exceptionCode == ERRNO_NOERR && infos->eventFd != -1 && infos->notifyFd != -1) { + auto ret = poll(fds, nfds, -1); + if (ret > 0) { + if (static_cast(fds[0].revents) & POLLNVAL) { + infos->run = false; + return; + } + if (static_cast(fds[1].revents) & POLLIN) { + ReadNotifyEventLocked(infos, callback); + } + } else if (ret < 0 && errno == EINTR) { + continue; + } else { + infos->exceptionCode = errno; + return; + } + { + std::unique_lock lock(callback->cvLock); + 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, const std::optional &options) +{ + auto infos = CreateSharedPtr(); + if (infos == nullptr) { + HILOGE("Failed to request heap memory."); + return { ENOMEM, nullptr }; + } + infos->srcUri = srcUri; + infos->destUri = destUri; + FileUri srcFileUri(infos->srcUri); + infos->srcPath = srcFileUri.GetRealPath(); + FileUri dstFileUri(infos->destUri); + infos->destPath = dstFileUri.GetPath(); + infos->srcPath = GetRealPath(infos->srcPath); + 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.has_value()) { + auto listener = options.value().progressListener; + if (listener) { + infos->hasListener = true; + infos->listener = listener; + } + 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) +{ + if (infos->hasListener && callback != nullptr) { + callback->notifyHandler = std::thread([infos] { GetNotifyEvent(infos); }); + } +} + +int CopyCore::ExecCopy(std::shared_ptr infos) +{ + if (infos->isFile && IsFile(infos->destPath)) { + // copyFile + return CopyFile(infos->srcPath.c_str(), infos->destPath.c_str(), infos); + } + if (!infos->isFile && IsDirectory(infos->destPath)) { + if (infos->srcPath.back() != '/') { + infos->srcPath += '/'; + } + if (infos->destPath.back() != '/') { + infos->destPath += '/'; + } + // copyDir + return CopyDirFunc(infos->srcPath.c_str(), infos->destPath.c_str(), infos); + } + return EINVAL; +} + +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 false; + } + return true; +} + +void CopyCore::WaitNotifyFinished(std::shared_ptr callback) +{ + if (callback != nullptr) { + if (callback->notifyHandler.joinable()) { + callback->notifyHandler.join(); + } + } +} + +void CopyCore::CopyComplete(std::shared_ptr infos, std::shared_ptr callback) +{ + if (callback != nullptr && infos->hasListener) { + callback->progressSize = callback->totalSize; + OnFileReceive(infos); + } +} + +FsResult CopyCore::DoCopy(const string &src, const string &dest, std::optional &options) +{ + 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); + if (callback == nullptr) { + return FsResult::Error(EINVAL); + } + + if (IsRemoteUri(infos->srcUri)) { + if (infos->taskSignal != nullptr) { + infos->taskSignal->MarkRemoteTask(); + } + 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(); + } + } + 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 { + return FsResult::Success(); + } +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_core.h new file mode 100644 index 0000000000000000000000000000000000000000..38779226062c433f42bc60b371d88aa76e463e87 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_core.h @@ -0,0 +1,192 @@ +/* + * 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_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H + +#include +#include +#include +#include +#include + +#include "bundle_mgr_client_impl.h" +#include "filemgmt_libfs.h" +#include "filemgmt_libhilog.h" +#include "fs_task_signal.h" +#include "i_progress_listener.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +using namespace OHOS::AppExecFwk; +using namespace DistributedFS::ModuleTaskSignal; + +struct CopyOptions { + std::shared_ptr progressListener; + std::shared_ptr copySignal; +}; + +struct ReceiveInfo { + std::string path; // dir name + std::map fileList; // filename, proceededSize +}; + +struct FsCallbackObject { + std::shared_ptr listener = nullptr; + int32_t notifyFd = -1; + int32_t eventFd = -1; + std::vector>> wds; + uint64_t totalSize = 0; + uint64_t progressSize = 0; + uint64_t maxProgressSize = 0; + int32_t errorCode = 0; + std::thread notifyHandler; + std::mutex readMutex; + std::condition_variable cv; + std::mutex cvLock; + bool reading = false; + bool closed = false; + explicit FsCallbackObject(std::shared_ptr listener) : listener(listener) {} + + void CloseFd() + { + if (eventFd != -1) { + close(eventFd); + eventFd = -1; + } + if (notifyFd == -1) { + return; + } + for (auto item : wds) { + inotify_rm_watch(notifyFd, item.first); + } + close(notifyFd); + notifyFd = -1; + } + + ~FsCallbackObject() + { + CloseFd(); + } +}; + +struct FsFileInfos { + std::string srcUri; + std::string destUri; + std::string srcPath; + std::string destPath; + bool isFile = false; + std::chrono::steady_clock::time_point notifyTime; + int32_t notifyFd = -1; + int32_t eventFd = -1; + bool run = true; + bool hasListener = false; + 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 FsFileInfos &infos) const + { + return (srcUri == infos.srcUri && destUri == infos.destUri); + } + bool operator<(const FsFileInfos &infos) const + { + if (srcUri == infos.srcUri) { + return destUri < infos.destUri; + } + return srcUri < infos.srcUri; + } +}; + +struct FsUvEntry { + std::shared_ptr callback; + std::shared_ptr fileInfos; + uint64_t progressSize = 0; + uint64_t totalSize = 0; + FsUvEntry(const std::shared_ptr &cb, std::shared_ptr fileInfos) + : callback(cb), fileInfos(fileInfos) + { + } + explicit FsUvEntry(const std::shared_ptr &cb) : callback(cb) {} +}; + +class CopyCore final { +public: + static FsResult DoCopy(const string &src, const string &dest, std::optional &options); + +private: + // operator of params + static bool ValidOperand(std::string uriStr); + static int CheckOrCreatePath(const std::string &destPath); + static bool ValidParams(const string &src, const string &dest); + + // operator of local listener + 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 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 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, 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 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); + + // operator of uri or path + static bool IsValidUri(const std::string &uri); + static bool IsRemoteUri(const std::string &uri); + static bool IsDirectory(const std::string &path); + 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); + +private: + static std::recursive_mutex mutex_; + static std::map> callbackMap_; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#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_dir_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b824647e3bbdac890da2eb9d6bfa87d096ee50a0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.cpp @@ -0,0 +1,257 @@ +/* + * 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_dir_core.h" + +#include +#include +#include +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static int RecurCopyDir( + const string &srcPath, const string &destPath, const int mode, vector &errfiles); + +static bool EndWithSlash(const string &src) +{ + return src.back() == '/'; +} + +static bool AllowToCopy(const string &src, const string &dest) +{ + if (src == dest) { + HILOGE("Failed to copy file, the same path"); + return false; + } + if (EndWithSlash(src) ? dest.find(src) == 0 : dest.find(src + "/") == 0) { + HILOGE("Failed to copy file, dest is under src"); + return false; + } + if (filesystem::path(src).parent_path() == dest) { + HILOGE("Failed to copy file, src's parent path is dest"); + return false; + } + return true; +} + +static tuple ParseAndCheckOperand(const string &src, const string &dest, const optional &mode) +{ + error_code errCode; + if (!filesystem::is_directory(filesystem::status(src, errCode))) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); + return { false, 0 }; + } + if (!filesystem::is_directory(filesystem::status(dest, errCode))) { + HILOGE("Invalid dest, errCode = %{public}d", errCode.value()); + return { false, 0 }; + } + if (!AllowToCopy(src, dest)) { + return { false, 0 }; + } + int32_t modeValue = 0; + if (mode.has_value()) { + modeValue = mode.value(); + if (modeValue < COPYMODE_MIN || modeValue > COPYMODE_MAX) { + HILOGE("Invalid mode"); + return { false, 0 }; + } + } + return { true, modeValue }; +} + +static int MakeDir(const string &path) +{ + filesystem::path destDir(path); + error_code errCode; + if (!filesystem::create_directory(destDir, errCode)) { + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +struct NameList { + struct dirent **namelist = { nullptr }; + int direntNum = 0; +}; + +static int RemoveFile(const string &destPath) +{ + filesystem::path destFile(destPath); + error_code errCode; + if (!filesystem::remove(destFile, errCode)) { + HILOGE("Failed to remove file with path, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +static void Deleter(struct NameList *arg) +{ + for (int i = 0; i < arg->direntNum; i++) { + free((arg->namelist)[i]); + (arg->namelist)[i] = nullptr; + } + free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; +} + +static int CopyFile(const string &src, const string &dest, const int mode) +{ + filesystem::path dstPath(dest); + error_code errCode; + if (filesystem::exists(dstPath, errCode)) { + int ret = (mode == DIRMODE_FILE_COPY_THROW_ERR) ? EEXIST : RemoveFile(dest); + if (ret) { + HILOGE("Failed to copy file due to existing destPath with throw err"); + return ret; + } + } + if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + filesystem::path srcPath(src); + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +static int CopySubDir( + const string &srcPath, const string &destPath, const int mode, vector &errfiles) +{ + error_code errCode; + if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { + int res = MakeDir(destPath); + if (res != ERRNO_NOERR) { + HILOGE("Failed to mkdir"); + return res; + } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + return RecurCopyDir(srcPath, destPath, mode, errfiles); +} + +static int FilterFunc(const struct dirent *filename) +{ + if (string_view(filename->d_name) == "." || string_view(filename->d_name) == "..") { + return DISMATCH; + } + return MATCH; +} + +static int RecurCopyDir( + const string &srcPath, const string &destPath, const int mode, vector &errfiles) +{ + unique_ptr pNameList = { new (nothrow) struct NameList, Deleter }; + if (pNameList == nullptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int num = scandir(srcPath.c_str(), &(pNameList->namelist), FilterFunc, alphasort); + if (num < 0) { + HILOGE("scandir fail errno is %{public}d", errno); + return errno; + } + pNameList->direntNum = num; + + for (int i = 0; i < num; i++) { + if ((pNameList->namelist[i])->d_type == DT_DIR) { + string srcTemp = srcPath + '/' + string((pNameList->namelist[i])->d_name); + string destTemp = destPath + '/' + string((pNameList->namelist[i])->d_name); + int res = CopySubDir(srcTemp, destTemp, mode, errfiles); + if (res == ERRNO_NOERR) { + continue; + } + return res; + } else { + string src = srcPath + '/' + string((pNameList->namelist[i])->d_name); + string dest = destPath + '/' + string((pNameList->namelist[i])->d_name); + int res = CopyFile(src, dest, mode); + if (res == EEXIST) { + errfiles.emplace_back(src, dest); + continue; + } else if (res == ERRNO_NOERR) { + continue; + } else { + HILOGE("Failed to copy file for error %{public}d", res); + return res; + } + } + } + return ERRNO_NOERR; +} + +static int CopyDirFunc(const string &src, const string &dest, const int mode, vector &errfiles) +{ + size_t found = string(src).rfind('/'); + if (found == string::npos) { + return EINVAL; + } + string dirName = string(src).substr(found); + string destStr = dest + dirName; + error_code errCode; + if (!filesystem::exists(destStr, errCode) && errCode.value() == ERRNO_NOERR) { + int res = MakeDir(destStr); + if (res != ERRNO_NOERR) { + HILOGE("Failed to mkdir"); + return res; + } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + int res = RecurCopyDir(src, destStr, mode, errfiles); + if (!errfiles.empty() && res == ERRNO_NOERR) { + return EEXIST; + } + return res; +} + +struct CopyDirResult CopyDirCore::DoCopyDir(const string &src, const string &dest, const optional &mode) +{ + auto [succ, modeValue] = ParseAndCheckOperand(src, dest, mode); + if (!succ) { + return { FsResult::Error(EINVAL), nullopt }; + } + + vector errfiles = {}; + int ret = CopyDirFunc(src, dest, modeValue, errfiles); + if (ret == EEXIST && modeValue == DIRMODE_FILE_COPY_THROW_ERR) { + return { FsResult::Error(EEXIST), make_optional>(move(errfiles)) }; + } else if (ret) { + return { FsResult::Error(ret), nullopt }; + } + return { FsResult::Success(), nullopt }; +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.h new file mode 100644 index 0000000000000000000000000000000000000000..e031e2a1d396195c5a7d22d3fcbd122fe6422d04 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.h @@ -0,0 +1,59 @@ +/* + * 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_DIR_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_DIR_CORE_H + +#include +#include + +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +constexpr int COPYMODE_MIN = 0; +constexpr int COPYMODE_MAX = 1; +constexpr int COPYDIR_DEFAULT_PERM = 0770; + +constexpr int DISMATCH = 0; +constexpr int MATCH = 1; + +enum ModeOfCopyDir { DIRMODE_FILE_COPY_THROW_ERR = 0, DIRMODE_FILE_COPY_REPLACE }; + +struct CopyDirResult { + FsResult fsResult; + optional> errFiles; +}; + +class CopyDirCore final { +public: + static struct CopyDirResult DoCopyDir( + const string &src, const string &dest, const optional &mode = nullopt); +}; + +struct ConflictFiles { + string srcFiles; + string destFiles; + ConflictFiles(const string &src, const string &dest) : srcFiles(src), destFiles(dest) {} + ~ConflictFiles() = default; +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_DIR_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 0000000000000000000000000000000000000000..ca3d9d9a150e27a821e6c894d1cef07f884d1116 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp @@ -0,0 +1,97 @@ +/* + * 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; + +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; +} + +static void SendCopyProgress(ani_vm *vm, ani_ref listener, uint64_t progressSize, uint64_t totalSize) +{ + 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; + } +} + +void ProgressListenerAni::InvokeListener(uint64_t progressSize, uint64_t totalSize) const +{ + auto localVm = vm; + auto localListener = listener; + auto task = [localVm, localListener, progressSize, totalSize]() { + SendCopyProgress(localVm, localListener, progressSize, totalSize); + }; + AniHelper::SendEventToMainThread(task); +} + +} // 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 0000000000000000000000000000000000000000..ccff55493d0203fe6271de928effbffd76cc3989 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h @@ -0,0 +1,36 @@ +/* + * 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: + 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/properties/copy_listener/i_progress_listener.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..f51f4f421562c0e603d9fea87025c27a425a7f72 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h @@ -0,0 +1,31 @@ +/* + * 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_I_PROGRESS_LISTENER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H + +#include + +namespace OHOS::FileManagement::ModuleFileIO { +const uint64_t MAX_VALUE = 0x7FFFFFFFFFFFFFFF; + +class IProgressListener { +public: + virtual ~IProgressListener() = default; + virtual void InvokeListener(uint64_t progressSize, uint64_t totalSize) const = 0; +}; + +} // 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 new file mode 100644 index 0000000000000000000000000000000000000000..0b8d32b788fa3c7acba5b86b378bb92d6e56ca19 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp @@ -0,0 +1,318 @@ +/* + * 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 "dfs_event_dfx.h" +#include "ipc_skeleton.h" +#include "sandbox_helper.h" +#include "uri.h" +#include "utils_log.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::AppFileService; +using namespace AppFileService::ModuleFileUri; +const std::string NETWORK_PARA = "?networkid="; +const std::string FILE_MANAGER_AUTHORITY = "docs"; +const std::string MEDIA_AUTHORITY = "media"; +const std::string DISTRIBUTED_PATH = "/data/storage/el2/distributedfiles/"; +std::atomic TransListenerCore::getSequenceId_ = 0; + +void TransListenerCore::RmDir(const std::string &path) +{ + HILOGI("RmDirm path : %{public}s", GetAnonyString(path).c_str()); + std::filesystem::path pathName(path); + std::error_code errCode; + if (std::filesystem::exists(pathName, errCode)) { + std::filesystem::remove_all(pathName, errCode); + if (errCode.value() != 0) { + HILOGE("Failed to remove directory, error code: %{public}d", errCode.value()); + } + } else { + HILOGE("pathName is not exists, error code: %{public}d", errCode.value()); + } +} + +std::string TransListenerCore::CreateDfsCopyPath() +{ + std::random_device rd; + std::string random = std::to_string(rd()); + while (std::filesystem::exists(DISTRIBUTED_PATH + random)) { + random = std::to_string(rd()); + } + return random; +} + +int TransListenerCore::HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, + const std::string &disSandboxPath, const std::string ¤tId) +{ + if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { + RmDir(disSandboxPath); + } + 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)); + 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)); + } + return it->second; +} + +int TransListenerCore::WaitForCopyResult(TransListenerCore *transListener) +{ + if (transListener == nullptr) { + HILOGE("transListener is nullptr"); + return FAILED; + } + std::unique_lock lock(transListener->cvMutex_); + transListener->cv_.wait(lock, [&transListener]() { + 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) +{ + HILOGI("CopyFileFromSoftBus begin."); + std::string currentId = "CopyFile_" + std::to_string(getpid()) + "_" + std::to_string(getSequenceId_); + ++getSequenceId_; + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN, RadarReporter::PACKAGE_NAME, std::to_string(getpid()), + RadarReporter::CONCURRENT_ID, currentId); + sptr transListener = new (std::nothrow) TransListenerCore(); + if (transListener == nullptr) { + HILOGE("new trans listener failed"); + return ENOMEM; + } + transListener->callback_ = std::move(callback); + + Storage::DistributedFile::HmdfsInfo info {}; + Uri uri(destUri); + info.authority = uri.GetAuthority(); + info.sandboxPath = SandboxHelper::Decode(uri.GetPath()); + std::string disSandboxPath; + auto ret = PrepareCopySession(srcUri, destUri, transListener, info, disSandboxPath); + if (ret != ERRNO_NOERR) { + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::PREPARE_COPY_SESSION_ERROR, RadarReporter::CONCURRENT_ID, currentId, + RadarReporter::PACKAGE_NAME, to_string(ret)); + return EIO; + } + if (fileInfos->taskSignal != nullptr) { + fileInfos->taskSignal->SetFileInfoOfRemoteTask(info.sessionName, fileInfos->srcPath); + } + auto copyResult = WaitForCopyResult(transListener); + if (copyResult == FAILED) { + return HandleCopyFailure(transListener->copyEvent_, info, disSandboxPath, currentId); + } + if (info.authority == FILE_MANAGER_AUTHORITY || info.authority == MEDIA_AUTHORITY) { + HILOGW("Public or media path not copy"); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId); + return ERRNO_NOERR; + } + + ret = CopyToSandBox(srcUri, disSandboxPath, info.sandboxPath, currentId); + RmDir(disSandboxPath); + if (ret != ERRNO_NOERR) { + HILOGE("CopyToSandBox failed, ret = %{public}d.", ret); + return EIO; + } + return ERRNO_NOERR; +} + +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) { + tmpDir = CreateDfsCopyPath(); + disSandboxPath = DISTRIBUTED_PATH + tmpDir; + std::error_code errCode; + if (!std::filesystem::create_directory(disSandboxPath, errCode)) { + HILOGE("Create dir failed, error code: %{public}d", errCode.value()); + return errCode.value(); + } + + auto pos = info.sandboxPath.rfind('/'); + if (pos == std::string::npos) { + HILOGE("invalid file path"); + return EIO; + } + auto sandboxDir = info.sandboxPath.substr(0, pos); + if (std::filesystem::exists(sandboxDir, errCode)) { + info.dirExistFlag = true; + } + } + + info.copyPath = tmpDir; + auto networkId = GetNetworkIdFromUri(srcUri); + HILOGI("dfs PrepareSession begin."); + 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) { + RmDir(disSandboxPath); + } + return EIO; + } + return ERRNO_NOERR; +} + +int32_t TransListenerCore::CopyToSandBox(const std::string &srcUri, const std::string &disSandboxPath, + const std::string &sandboxPath, const std::string ¤tId) +{ + std::error_code errCode; + if (std::filesystem::exists(sandboxPath) && std::filesystem::is_directory(sandboxPath)) { + HILOGI("Copy dir"); + std::filesystem::copy(disSandboxPath, sandboxPath, + std::filesystem::copy_options::recursive | std::filesystem::copy_options::update_existing, errCode); + if (errCode.value() != 0) { + HILOGE("Copy dir failed: errCode: %{public}d", errCode.value()); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::COPY_TO_SANDBOX_ERROR, RadarReporter::CONCURRENT_ID, currentId, + RadarReporter::PACKAGE_NAME, to_string(errCode.value())); + return EIO; + } + } else { + HILOGI("Copy file."); + Uri uri(srcUri); + auto fileName = GetFileName(uri.GetPath()); + if (fileName.empty()) { + HILOGE("Get filename failed"); + RmDir(disSandboxPath); + return EIO; + } + 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, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::COPY_TO_SANDBOX_ERROR, RadarReporter::CONCURRENT_ID, currentId, + RadarReporter::PACKAGE_NAME, to_string(errCode.value())); + return EIO; + } + } + HILOGI("Copy file success."); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId); + return ERRNO_NOERR; +} + +std::string TransListenerCore::GetFileName(const std::string &path) +{ + auto pos = path.find_last_of('/'); + if (pos == std::string::npos) { + HILOGE("invalid path"); + return ""; + } + return SandboxHelper::Decode(path.substr(pos)); +} + +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) +{ + if (entry == nullptr) { + HILOGE("entry pointer is nullptr."); + return; + } + + 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) +{ + std::lock_guard lock(callbackMutex_); + if (callback_ == nullptr) { + HILOGE("Failed to parse watcher callback"); + return ENOMEM; + } + + std::shared_ptr entry = std::make_shared(callback_); + if (entry == nullptr) { + HILOGE("entry ptr is nullptr"); + return ENOMEM; + } + entry->progressSize = processedBytes; + entry->totalSize = totalBytes; + CallbackComplete(entry); + return ERRNO_NOERR; +} + +int32_t TransListenerCore::OnFinished(const std::string &sessionName) +{ + HILOGI("OnFinished"); + { + std::lock_guard lock(callbackMutex_); + callback_ = nullptr; + } + { + std::lock_guard lock(cvMutex_); + copyEvent_.copyResult = SUCCESS; + cv_.notify_all(); + } + return ERRNO_NOERR; +} + +int32_t TransListenerCore::OnFailed(const std::string &sessionName, int32_t errorCode) +{ + HILOGI("OnFailed, errorCode is %{public}d", errorCode); + { + std::lock_guard lock(callbackMutex_); + callback_ = nullptr; + } + { + std::lock_guard lock(cvMutex_); + copyEvent_.copyResult = FAILED; + copyEvent_.errorCode = errorCode; + cv_.notify_all(); + } + return ERRNO_NOERR; +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..9688e794034b49af885e6fd22df7c844339effcd --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h @@ -0,0 +1,70 @@ +/* + * 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_TRANS_LISTENER_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H + +#include + +#include "copy_core.h" +#include "distributed_file_daemon_manager.h" +#include "file_trans_listener_stub.h" +#include "file_uri.h" +#include "hmdfs_info.h" +#include "uv.h" + +constexpr int NONE = 0; +constexpr int SUCCESS = 1; +constexpr int FAILED = 2; +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +struct CopyEvent { + int copyResult = NONE; + int32_t errorCode = 0; +}; +class TransListenerCore : public Storage::DistributedFile::FileTransListenerStub { +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); + +private: + static std::string GetNetworkIdFromUri(const std::string &uri); + 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 int HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, + const std::string &disSandboxPath, const std::string ¤tId); + 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_; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H diff --git a/interfaces/kits/js/src/mod_fs/properties/create_randomaccessfile_core.h b/interfaces/kits/js/src/mod_fs/properties/create_randomaccessfile_core.h index 0900891bae980358ec50348db1ee807f88c6149f..b8490a68c23f33a1964b08caa98044483bd8d03c 100644 --- a/interfaces/kits/js/src/mod_fs/properties/create_randomaccessfile_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/create_randomaccessfile_core.h @@ -38,7 +38,6 @@ public: static FsResult DoCreateRandomAccessFile( const int32_t &fd, const optional &options = nullopt); }; - } // namespace ModuleFileIO } // namespace FileManagement } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream_core.cpp b/interfaces/kits/js/src/mod_fs/properties/create_stream_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e17d5a1ba01ff3880d99d8cabe5a96dcd5f962e6 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream_core.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "create_stream_core.h" + +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_utils.h" +#include "stream_instantiator.h" +#include "stream_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult CreateStreamCore::DoCreateStream(const std::string &path, const std::string &mode) +{ + FILE *file = fopen(path.c_str(), mode.c_str()); + if (!file) { + HILOGE("Failed to fopen file by path"); + return FsResult::Error(errno); + } + + return StreamInstantiator::InstantiateStream(move(file)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/create_stream_core.h b/interfaces/kits/js/src/mod_fs/properties/create_stream_core.h new file mode 100644 index 0000000000000000000000000000000000000000..8c0a2aade48bf44ad726e580d500a099d2ad086c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/create_stream_core.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_CREATE_STREAM_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_stream.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class CreateStreamCore final { +public: + static FsResult DoCreateStream(const std::string &path, const std::string &mode); +}; + +struct AsyncCreateStreamArg { + std::shared_ptr fp { nullptr }; +}; + +const std::string PROCEDURE_CREATESTREAM_NAME = "FileIOCreateStream"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_CREATE_STREAM_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.cpp b/interfaces/kits/js/src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a77a6ff2608a06fc87fa16bcdfefedc29b0a0ded --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 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 "file_dfs_listener_stub.h" +#include "file_dfs_listener_interface_code.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace FileManagement; +namespace { + constexpr int NO_ERROR = 0; + constexpr int E_INVAL_ARG = 1; +} + +FileDfsListenerStub::FileDfsListenerStub() +{ + opToInterfaceMap_[static_cast + (Storage::DistributedFile::FileDfsListenerInterfaceCode::FILE_DFS_LISTENER_ON_STATUS)] = + &FileDfsListenerStub::HandleOnStatus; +} + +int32_t FileDfsListenerStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, + MessageParcel &reply, + MessageOption &option) +{ + if (data.ReadInterfaceToken() != GetDescriptor()) { + return FILE_DFS_LISTENER_DESCRIPTOR_IS_EMPTY; + } + switch (code) { + case static_cast(Storage::DistributedFile::FileDfsListenerInterfaceCode::FILE_DFS_LISTENER_ON_STATUS): + return HandleOnStatus(data, reply); + default: + HILOGE("Cannot response request %{public}d: unknown tranction", code); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} + +int32_t FileDfsListenerStub::HandleOnStatus(MessageParcel &data, MessageParcel &reply) +{ + std::string networkId; + if (!data.ReadString(networkId)) { + HILOGE("read networkId failed"); + return E_INVAL_ARG; + } + int32_t status; + if (!data.ReadInt32(status)) { + HILOGE("read status failed"); + return E_INVAL_ARG; + } + if (networkId.empty() || status < 0) { + HILOGE("Invalid arguments"); + return E_INVAL_ARG; + } + OnStatus(networkId, status); + return NO_ERROR; +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.h b/interfaces/kits/js/src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..bafb64cad07fb244e8cf1660e40ccd7a98c0dc67 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/dfs_listener/file_dfs_listener_stub.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_FILE_API_FILE_DFS_LISTENER_STUB_H +#define FILEMANAGEMENT_FILE_API_FILE_DFS_LISTENER_STUB_H + +#include +#include "i_file_dfs_listener.h" +#include "iremote_stub.h" +#include "message_option.h" +#include "message_parcel.h" +#include "refbase.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class FileDfsListenerStub : public IRemoteStub { +public: + FileDfsListenerStub(); + virtual ~FileDfsListenerStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using FileDfsListenerInterface = int32_t (FileDfsListenerStub::*)(MessageParcel &data, MessageParcel &reply); + std::map opToInterfaceMap_; + + int32_t HandleOnStatus(MessageParcel &data, MessageParcel &reply); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // FILEMANAGEMENT_FILE_API_FILE_DFS_LISTENER_STUB_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/disconnectdfs_core.cpp b/interfaces/kits/js/src/mod_fs/properties/disconnectdfs_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92020ae3773f11e620f7b593b916931100a87aa5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/disconnectdfs_core.cpp @@ -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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "filemgmt_libhilog.h" +#include "distributed_file_daemon_manager.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace fs = std::filesystem; + +FsResult DisConnectDfsCore::DisConnectDfsExec(const std::string &networkId) +{ + if (networkId == "") { + return FsResult::Error(E_PARAMS); + } + + int result = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance(). + CloseP2PConnectionEx(networkId); + if (result != ERRNO_NOERR) { + HILOGE("Fail to Closep2pconnection"); + return FsResult::Error(result); + } + return FsResult::Success(); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/disconnectdfs_core.h b/interfaces/kits/js/src/mod_fs/properties/disconnectdfs_core.h new file mode 100644 index 0000000000000000000000000000000000000000..0cc11a1b903c78a145c3500566a561dcee98d70c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/disconnectdfs_core.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_DISCONNECTDFS_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_DISCONNECTDFS_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_utils.h" +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class DisConnectDfsCore final { +public: + static FsResult DisConnectDfsExec(const std::string &networkId); +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_DISCONNECTDFS_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdatasync_core.cpp b/interfaces/kits/js/src/mod_fs/properties/fdatasync_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..38996fda03d167806fb900266596364df9b134f0 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdatasync_core.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fdatasync_core.h" + +#include +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +FsResult FDataSyncCore::DoFDataSync(const int32_t &fd) +{ + std::unique_ptr fDataSyncReq = { new uv_fs_t, FsUtils::FsReqCleanup }; + if (!fDataSyncReq) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + + int ret = uv_fs_fdatasync(nullptr, fDataSyncReq.get(), fd, nullptr); + if (ret < 0) { + HILOGE("Failed to transfer data associated with file descriptor: %{public}d, ret:%{public}d", fd, ret); + return FsResult::Error(ret); + } + + return FsResult::Success(); +} + +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdatasync_core.h b/interfaces/kits/js/src/mod_fs/properties/fdatasync_core.h new file mode 100644 index 0000000000000000000000000000000000000000..5e26c9140dc98c0d582a2ac75d743ae1618546d1 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdatasync_core.h @@ -0,0 +1,29 @@ +/* + * 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_FDATASYNC_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDATASYNC_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_utils.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class FDataSyncCore final { +public: + static FsResult DoFDataSync(const int32_t &fd); +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDATASYNC_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream_core.cpp b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4337cd766b644ce8949f7643ff2816c8013f386d --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream_core.cpp @@ -0,0 +1,49 @@ +/* + * 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 "fdopen_stream_core.h" + +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_utils.h" +#include "stream_instantiator.h" +#include "stream_entity.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult FdopenStreamCore::DoFdopenStream(const int &fd, const string &mode) +{ + if (fd < 0) { + HILOGE("Invalid fd"); + return FsResult::Error(EINVAL); + } + + FILE *file = fdopen(fd, mode.c_str()); + if (!file) { + HILOGE("Failed to fopen file by fd"); + return FsResult::Error(errno); + } + + return StreamInstantiator::InstantiateStream(move(file)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fdopen_stream_core.h b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream_core.h new file mode 100644 index 0000000000000000000000000000000000000000..a319480fdd0c2aad52dc938f1b0512cc529776e6 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fdopen_stream_core.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_FDOPEN_STREAM_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_stream.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class FdopenStreamCore final { +public: + static FsResult DoFdopenStream(const int &fd, const string &mode); +}; + +struct AsyncFdopenStreamArg { + std::shared_ptr fp { nullptr }; +}; + +const std::string PROCEDURE_FDOPENSTREAM_NAME = "FileIOFdopenStream"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FDOPEN_STREAM_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fsync_core.cpp b/interfaces/kits/js/src/mod_fs/properties/fsync_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d902ff1f31e2dc4aa125bffbbff40378278b8ecc --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fsync_core.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fsync_core.h" + +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "fs_utils.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +FsResult FsyncCore::DoFsync(const int32_t &fd) +{ + std::unique_ptr fsyncReq = { new uv_fs_t, FsUtils::FsReqCleanup }; + if (!fsyncReq) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + int ret = uv_fs_fsync(nullptr, fsyncReq.get(), fd, nullptr); + if (ret < 0) { + HILOGE("Failed to transfer data associated with file descriptor: %{public}d", fd); + return FsResult::Error(ret); + } + return FsResult::Success(); +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/fsync_core.h b/interfaces/kits/js/src/mod_fs/properties/fsync_core.h new file mode 100644 index 0000000000000000000000000000000000000000..ce2b6683555e973823b80a0582bb8e9a66e3f322 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/fsync_core.h @@ -0,0 +1,29 @@ +/* + * 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_FSYNC_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FSYNC_CORE_H + +#include "filemgmt_libfs.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +class FsyncCore final { +public: + static FsResult DoFsync(const int32_t &fd); +}; +const std::string PROCEDURE_FSYNC_NAME = "FileIOFsync"; +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_FSYNC_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/lseek_core.cpp b/interfaces/kits/js/src/mod_fs/properties/lseek_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfec873c9cf2bea50fb4fb2932408c95ca116a2c --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/lseek_core.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lseek_core.h" + +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult LseekCore::DoLseek(const int32_t &fd, const int64_t &offset, + const optional &pos) +{ + if (fd < 0) { + HILOGE("Invalid fd from JS first argument"); + return FsResult::Error(EINVAL); + } + + SeekPos whence = SeekPos::START; + if (pos.has_value()) { + if (pos.value() < SeekPos::START || pos.value() > SeekPos::END) { + HILOGE("Invalid whence from JS third argument"); + return FsResult::Error(EINVAL); + } + whence = pos.value(); + } + + int64_t ret = ::Lseek(fd, offset, whence); + if (ret < 0) { + HILOGE("Failed to lseek, error:%{public}d", errno); + return FsResult::Error(errno); + } + + return FsResult::Success(ret); +} + +} // ModuleFileIO +} // FileManagement +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/lseek_core.h b/interfaces/kits/js/src/mod_fs/properties/lseek_core.h new file mode 100644 index 0000000000000000000000000000000000000000..dd399f652e37dbe23edc17b24be32b74d1f19536 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/lseek_core.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSEEK_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSEEK_CORE_H + +#include "filemgmt_libfs.h" +#include "rust_file.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +class LseekCore final { +public: + static FsResult DoLseek(const int32_t &fd, const int64_t &offset, + const optional &pos = nullopt); +}; + +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSEEK_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/lstat_core.h b/interfaces/kits/js/src/mod_fs/properties/lstat_core.h index 86748ea5f0c9cf609ded0af76280a07de69fbe19..c55d6eb3a8add6318937940f2a97ef5318bd1f9e 100644 --- a/interfaces/kits/js/src/mod_fs/properties/lstat_core.h +++ b/interfaces/kits/js/src/mod_fs/properties/lstat_core.h @@ -25,6 +25,5 @@ class LstatCore final { public: static FsResult DoLstat(const string &path); }; - } // namespace OHOS::FileManagement::ModuleFileIO #endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_LSTAT_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/mkdtemp_core.cpp b/interfaces/kits/js/src/mod_fs/properties/mkdtemp_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..487f35c69e38f90b309425a64e7b16ae4b4ae33e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/mkdtemp_core.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mkdtemp_core.h" + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult MkdtempCore::DoMkdtemp(const string &path) +{ + unique_ptr mkdtempReq = { new uv_fs_t, FsUtils::FsReqCleanup }; + if (!mkdtempReq) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + int ret = uv_fs_mkdtemp(nullptr, mkdtempReq.get(), const_cast(path.c_str()), nullptr); + if (ret < 0) { + HILOGE("Failed to create a temporary directory with path"); + return FsResult::Error(ret); + } + + return FsResult::Success(move(mkdtempReq->path)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fs/properties/mkdtemp_core.h b/interfaces/kits/js/src/mod_fs/properties/mkdtemp_core.h new file mode 100644 index 0000000000000000000000000000000000000000..df936597f265e739e766715b4792ab4c565a8688 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/mkdtemp_core.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MKDTEMP_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MKDTEMP_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +class MkdtempCore final { +public: + static FsResult DoMkdtemp(const std::string &path); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MKDTEMP_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir_core.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb357ff05a3a69c00db190eb57a16472988fd709 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/movedir_core.cpp @@ -0,0 +1,306 @@ +/* + * 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 "movedir_core.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, + deque &errfiles); + +static tuple JudgeExistAndEmpty(const string &path) +{ + std::error_code errCode; + filesystem::path pathName(path); + if (filesystem::exists(pathName, errCode)) { + if (filesystem::is_empty(pathName, errCode)) { + return { true, true }; + } + return { true, false }; + } + return { false, false }; +} + +static int RmDirectory(const string &path) +{ + filesystem::path pathName(path); + std::error_code errCode; + if (filesystem::exists(pathName, errCode)) { + std::error_code errCode; + (void)filesystem::remove_all(pathName, errCode); + if (errCode.value() != 0) { + HILOGE("Failed to remove directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +static int RemovePath(const string& pathStr) +{ + filesystem::path pathTarget(pathStr); + std::error_code errCode; + if (!filesystem::remove(pathTarget, errCode)) { + HILOGE("Failed to remove file or directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +static int CopyAndDeleteFile(const string &src, const string &dest) +{ + filesystem::path dstPath(dest); + std::error_code errCode; + if (filesystem::exists(dstPath, errCode)) { + int removeRes = RemovePath(dest); + if (removeRes != 0) { + HILOGE("Failed to remove dest file"); + return removeRes; + } + } + filesystem::path srcPath(src); + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return RemovePath(src); +} + +static int RenameFile(const string &src, const string &dest, const int mode, deque &errfiles) +{ + filesystem::path dstPath(dest); + std::error_code errCode; + if (filesystem::exists(dstPath, errCode)) { + if (filesystem::is_directory(dstPath, errCode)) { + errfiles.emplace_front(src, dest); + return ERRNO_NOERR; + } + if (mode == DIRMODE_FILE_THROW_ERR) { + errfiles.emplace_back(src, dest); + return ERRNO_NOERR; + } + } + if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists or is_directory fail, errcode is %{public}d", errCode.value()); + } + filesystem::path srcPath(src); + filesystem::rename(srcPath, dstPath, errCode); + if (errCode.value() == EXDEV) { + HILOGD("Failed to rename file due to EXDEV"); + return CopyAndDeleteFile(src, dest); + } + return errCode.value(); +} + +static int32_t FilterFunc(const struct dirent *filename) +{ + if (string_view(filename->d_name) == "." || string_view(filename->d_name) == "..") { + return FILE_DISMATCH; + } + return FILE_MATCH; +} + +static int RenameDir(const string &src, const string &dest, const int mode, deque &errfiles) +{ + filesystem::path destPath(dest); + std::error_code errCode; + if (filesystem::exists(destPath, errCode)) { + return RecurMoveDir(src, dest, mode, errfiles); + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + filesystem::path srcPath(src); + filesystem::rename(srcPath, destPath, errCode); + if (errCode.value() == EXDEV) { + HILOGD("Failed to rename file due to EXDEV"); + if (!filesystem::create_directory(destPath, errCode)) { + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return RecurMoveDir(src, dest, mode, errfiles); + } + if (errCode.value() != 0) { + HILOGE("Failed to rename file, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +struct NameListArg { + struct dirent** namelist; + int num; +}; + +static void Deleter(struct NameListArg *arg) +{ + for (int i = 0; i < arg->num; i++) { + free((arg->namelist)[i]); + (arg->namelist)[i] = nullptr; + } + free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; +} + +static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, + deque &errfiles) +{ + filesystem::path dpath(destPath); + std::error_code errCode; + if (!filesystem::is_directory(dpath, errCode)) { + errfiles.emplace_front(srcPath, destPath); + return ERRNO_NOERR; + } + + unique_ptr ptr = {new struct NameListArg, Deleter}; + if (!ptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int num = scandir(srcPath.c_str(), &(ptr->namelist), FilterFunc, alphasort); + ptr->num = num; + + for (int i = 0; i < num; i++) { + if ((ptr->namelist[i])->d_type == DT_DIR) { + string srcTemp = srcPath + '/' + string((ptr->namelist[i])->d_name); + string destTemp = destPath + '/' + string((ptr->namelist[i])->d_name); + size_t size = errfiles.size(); + int res = RenameDir(srcTemp, destTemp, mode, errfiles); + if (res != ERRNO_NOERR) { + return res; + } + if (size != errfiles.size()) { + continue; + } + res = RemovePath(srcTemp); + if (res) { + return res; + } + } else { + string src = srcPath + '/' + string((ptr->namelist[i])->d_name); + string dest = destPath + '/' + string((ptr->namelist[i])->d_name); + int res = RenameFile(src, dest, mode, errfiles); + if (res != ERRNO_NOERR) { + HILOGE("Failed to rename file for error %{public}d", res); + return res; + } + } + } + return ERRNO_NOERR; +} + +static int MoveDirFunc(const string &src, const string &dest, const int mode, deque &errfiles) +{ + size_t found = string(src).rfind('/'); + if (found == std::string::npos) { + return EINVAL; + } + if (access(src.c_str(), W_OK) != 0) { + HILOGE("Failed to move src directory due to doesn't exist or hasn't write permission"); + return errno; + } + string dirName = string(src).substr(found); + string destStr = dest + dirName; + auto [destStrExist, destStrEmpty] = JudgeExistAndEmpty(destStr); + if (destStrExist && !destStrEmpty) { + if (mode == DIRMODE_DIRECTORY_REPLACE) { + int removeRes = RmDirectory(destStr); + if (removeRes) { + HILOGE("Failed to remove dest directory in DIRMODE_DIRECTORY_REPLACE"); + return removeRes; + } + } + if (mode == DIRMODE_DIRECTORY_THROW_ERR) { + HILOGE("Failed to move directory in DIRMODE_DIRECTORY_THROW_ERR"); + return ENOTEMPTY; + } + } + int res = RenameDir(src, destStr, mode, errfiles); + if (res == ERRNO_NOERR) { + if (!errfiles.empty()) { + HILOGE("Failed to movedir with some conflicted files"); + return EEXIST; + } + int removeRes = RmDirectory(src); + if (removeRes) { + HILOGE("Failed to remove src directory"); + return removeRes; + } + } + return res; +} + +static tuple ValidMoveDirArg( + const string &src, const string &dest, optional mode) +{ + std::error_code errCode; + if (!filesystem::is_directory(filesystem::status(src.c_str(), errCode))) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); + return { false, 0 }; + } + if (!filesystem::is_directory(filesystem::status(dest.c_str(), errCode))) { + HILOGE("Invalid dest,errCode = %{public}d", errCode.value()); + return { false, 0 }; + } + int modeType = 0; + if (mode.has_value()) { + modeType = mode.value(); + if (modeType < DIRMODE_MIN || modeType > DIRMODE_MAX) { + HILOGE("Invalid mode"); + return { false, 0 }; + } + } + return { true, modeType }; +} + +MoveDirResult MoveDirCore::DoMoveDir( + const string &src, const string &dest, optional modeType) +{ + auto [succ, mode] = ValidMoveDirArg(src, dest, modeType); + if (!succ) { + return { FsResult::Error(EINVAL), nullopt }; + } + deque errfiles = {}; + int ret = MoveDirFunc(src, dest, mode, errfiles); + if (ret == EEXIST) { + return { FsResult::Error(EEXIST), optional> { errfiles } }; + } else if (ret) { + return { FsResult::Error(ret), nullopt }; + } + return { FsResult::Success(), nullopt }; +} + +} // ModuleFileIO +} // FileManagement +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir_core.h b/interfaces/kits/js/src/mod_fs/properties/movedir_core.h new file mode 100755 index 0000000000000000000000000000000000000000..f10eaa5321bce542448c6d5bce604c63e6060f7a --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/movedir_core.h @@ -0,0 +1,64 @@ +/* + * 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_MOVEDIR_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MOVEDIR_CORE_H + +#include +#include + +#include "filemgmt_libfs.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { + +constexpr int DIRMODE_MIN = 0; +constexpr int DIRMODE_MAX = 3; + +constexpr int FILE_DISMATCH = 0; +constexpr int FILE_MATCH = 1; +constexpr int MOVEDIR_DEFAULT_PERM = 0770; + +enum ModeOfMoveDir { + DIRMODE_DIRECTORY_THROW_ERR = 0, + DIRMODE_FILE_THROW_ERR, + DIRMODE_FILE_REPLACE, + DIRMODE_DIRECTORY_REPLACE +}; + +struct ErrFiles { + std::string srcFiles; + std::string destFiles; + ErrFiles(const std::string& src, const std::string& dest) : srcFiles(src), destFiles(dest) {} + ~ErrFiles() = default; +}; + +struct MoveDirResult { + FsResult fsResult; + optional> errFiles; +}; + +class MoveDirCore final { +public: + static MoveDirResult DoMoveDir( + const std::string &src, const std::string &dest, std::optional mode = std::nullopt); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_MOVEDIR_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/read_lines_core.cpp b/interfaces/kits/js/src/mod_fs/properties/read_lines_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f986915199031de14d6eedf10ebb6115003e9c6 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/read_lines_core.cpp @@ -0,0 +1,106 @@ +/* + * 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 "read_lines_core.h" + +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "rust_file.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static int CheckOptionArg(Options option) +{ + auto encoding = option.encoding; + if (encoding != "utf-8") { + return EINVAL; + } + + return ERRNO_NOERR; +} + +static int GetFileSize(const string &path, int64_t &offset) +{ + std::unique_ptr readLinesReq = { new uv_fs_t, FsUtils::FsReqCleanup }; + if (!readLinesReq) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + + int ret = uv_fs_stat(nullptr, readLinesReq.get(), path.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to get file stat by path"); + return ret; + } + + offset = static_cast(readLinesReq->statbuf.st_size); + return ERRNO_NOERR; +} + +static FsResult InstantiateReaderIterator(void *iterator, int64_t offset) +{ + if (iterator == nullptr) { + HILOGE("Invalid argument iterator"); + return FsResult::Error(EINVAL); + } + + auto readeriterator = FsReaderIterator::Constructor(); + if (!readeriterator.IsSuccess()) { + HILOGE("Failed to instantiate class ReaderIterator"); + return FsResult::Error(UNKNOWN_ERR); + } + + auto readerIteratorEntity = readeriterator.GetData().value()->GetReaderIteratorEntity(); + if (!readerIteratorEntity) { + HILOGE("Failed to get readerIteratorEntity"); + return FsResult::Error(UNKNOWN_ERR); + } + readerIteratorEntity->iterator = iterator; + readerIteratorEntity->offset = offset; + return FsResult::Success(readeriterator.GetData().value()); +} + +FsResult ReadLinesCore::DoReadLines(const string &path, optional option) +{ + if (option.has_value()) { + int ret = CheckOptionArg(option.value()); + if (ret) { + HILOGE("Invalid option.encoding parameter"); + return FsResult::Error(ret); + } + } + + auto iterator = ::ReaderIterator(path.c_str()); + if (iterator == nullptr) { + HILOGE("Failed to read lines of the file, error: %{public}d", errno); + return FsResult::Error(errno); + } + + int64_t offset = 0; + int ret = GetFileSize(path, offset); + if (ret != 0) { + HILOGE("Failed to get size of the file"); + return FsResult::Error(ret); + } + return InstantiateReaderIterator(iterator, offset); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/symlink_core.cpp b/interfaces/kits/js/src/mod_fs/properties/symlink_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..217f429fd20e7a4e1c8b53fbbfbd3bdb4f067010 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/symlink_core.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "symlink_core.h" + +#include +#include +#include +#include + +#include "filemgmt_libhilog.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult SymlinkCore::DoSymlink(const string &target, const string &srcPath) +{ + std::unique_ptr symlinkReq = { new uv_fs_t, FsUtils::FsReqCleanup }; + if (!symlinkReq) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + int ret = uv_fs_symlink(nullptr, symlinkReq.get(), target.c_str(), srcPath.c_str(), 0, nullptr); + if (ret < 0) { + HILOGE("Failed to create a link for old path"); + return FsResult::Error(ret); + } + return FsResult::Success(); +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/symlink_core.h b/interfaces/kits/js/src/mod_fs/properties/symlink_core.h new file mode 100644 index 0000000000000000000000000000000000000000..223c8b683d30b409e5c9882386d0e92632c64741 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/symlink_core.h @@ -0,0 +1,32 @@ +/* + * 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_SYMLINK_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_SYMLINK_CORE_H + +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class SymlinkCore final { +public: + static FsResult DoSymlink(const string &target, const string &srcPath); +}; +const std::string PROCEDURE_RMDIRENT_NAME = "FileIOSymLink"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_SYMLINK_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/utimes_core.cpp b/interfaces/kits/js/src/mod_fs/properties/utimes_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b517167bf69d8fbbee4b590ba089d193c6c7746 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/utimes_core.cpp @@ -0,0 +1,64 @@ +/* + * 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 "utimes_core.h" + +#include + +#include "filemgmt_libhilog.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +FsResult UtimesCore::DoUtimes(const string &path, const double mtime) +{ + if (mtime < 0) { + HILOGE("Invalid mtime"); + return FsResult::Error(EINVAL); + } + std::unique_ptr statReq = { + new (std::nothrow) uv_fs_t, FsUtils::FsReqCleanup }; + if (!statReq) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + int ret = uv_fs_stat(nullptr, statReq.get(), path.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to get stat of the file by path"); + return FsResult::Error(ret); + } + + std::unique_ptr utimesReq = { + new uv_fs_t, FsUtils::FsReqCleanup }; + if (!utimesReq) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + + double atime = static_cast(statReq->statbuf.st_atim.tv_sec) + + static_cast(statReq->statbuf.st_atim.tv_nsec) / NS; + ret = uv_fs_utime(nullptr, utimesReq.get(), path.c_str(), atime, mtime / MS, nullptr); + if (ret < 0) { + HILOGE("Failed to chang mtime of the file for %{public}d", ret); + return FsResult::Error(ret); + } + return FsResult::Success(); +} +} // ModuleFileIO +} // FileManagement +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/utimes_core.h b/interfaces/kits/js/src/mod_fs/properties/utimes_core.h new file mode 100644 index 0000000000000000000000000000000000000000..86fe8c4fd83dded66c52ddf571c158e1799330a6 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/utimes_core.h @@ -0,0 +1,32 @@ +/* + * 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_UTIMES_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_UTIMES_CORE_H + +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class UtimesCore final { +public: + static FsResult DoUtimes(const string &path, const double mtime); +}; +const std::string PROCEDURE_RMDIRENT_NAME = "FileIOUtimes"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_UTIMES_CORE_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 new file mode 100644 index 0000000000000000000000000000000000000000..1ea4a713a55989c1340331c6c47ef623c5a57711 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/watcher_core.cpp @@ -0,0 +1,108 @@ +/* + * 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_core.h" + +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_file_watcher.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +static FsResult InstantiateWatcher() +{ + if (FsFileWatcher::GetInstance().GetNotifyId() < 0 && !FsFileWatcher::GetInstance().InitNotify()) { + HILOGE("Failed to get notifyId or initnotify fail"); + return FsResult::Error(errno); + } + FsResult result = FsWatcher::Constructor(); + if (!result.IsSuccess()) { + HILOGE("Failed to instantiate watcher"); + return FsResult::Error(EIO); + } + return result; +} + +shared_ptr ToWatcherInfo( + const string &path, const int32_t events, shared_ptr callback, int32_t &errCode) +{ + if (events <= 0 || !FsFileWatcher::GetInstance().CheckEventValid(events)) { + HILOGE("Failed to get watcher event."); + errCode = EINVAL; + return nullptr; + } + + if (!callback) { + HILOGE("Failed to get callback"); + errCode = EINVAL; + return nullptr; + } + + auto info = CreateSharedPtr(callback); + if (info == nullptr) { + HILOGE("Failed to request heap memory."); + errCode = ENOMEM; + return nullptr; + } + + info->events = static_cast(events); + info->fileName = move(path); + return info; +} + +FsResult WatcherCore::DoCreateWatcher( + const string &path, const int32_t events, shared_ptr callback) +{ + int errCode = 0; + auto info = ToWatcherInfo(path, events, callback, errCode); + if (errCode != 0) { + HILOGE("Failed to parse param"); + return FsResult::Error(errCode); + } + + auto result = InstantiateWatcher(); + if (!result.IsSuccess()) { + return result; + } + + const FsWatcher *objWatcher = result.GetData().value(); + if (!objWatcher) { + HILOGE("Failed to get fsWatcher"); + return FsResult::Error(EIO); + } + + auto *watchEntity = objWatcher->GetWatchEntity(); + if (!watchEntity) { + HILOGE("Failed to get watchEntity."); + delete objWatcher; + objWatcher = nullptr; + return FsResult::Error(EIO); + } + + watchEntity->data_ = info; + + bool ret = FsFileWatcher::GetInstance().AddWatcherInfo(info); + if (!ret) { + HILOGE("Failed to add watcher info."); + return FsResult::Error(EINVAL); + } + return result; +} +} // namespace OHOS::FileManagement::ModuleFileIO diff --git a/interfaces/kits/js/src/mod_fs/properties/watcher_core.h b/interfaces/kits/js/src/mod_fs/properties/watcher_core.h new file mode 100644 index 0000000000000000000000000000000000000000..4a303dbcb490026b810424621226cb82e6d11a31 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/watcher_core.h @@ -0,0 +1,32 @@ +/* + * 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_WATCHER_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_WATCHER_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_watch_entity.h" +#include "fs_watcher.h" + +namespace OHOS::FileManagement::ModuleFileIO { + +class WatcherCore final { +public: + static FsResult DoCreateWatcher( + const std::string &path, const int32_t events, std::shared_ptr callback); +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_WATCHER_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/xattr_core.cpp b/interfaces/kits/js/src/mod_fs/properties/xattr_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba22e42c7a4c80b9efda1ace164541f35819eff5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/xattr_core.cpp @@ -0,0 +1,87 @@ +/* + * 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 "xattr_core.h" + +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +constexpr size_t MAX_XATTR_SIZE = 4096; + +static bool IsIllegalXattr(const char *key, const char *value) +{ + bool isIllegalKey = strnlen(key, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE; + if (isIllegalKey) { + HILOGE("key is too long"); + } + bool isIllegalValue = strnlen(value, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE; + if (isIllegalValue) { + HILOGE("value is too long"); + } + return isIllegalKey || isIllegalValue; +} + +static int32_t GetXattrCore(const char *path, const char *key, std::shared_ptr result) +{ + ssize_t xAttrSize = getxattr(path, key, nullptr, 0); + if (xAttrSize == -1 || xAttrSize == 0) { + *result = ""; + return ERRNO_NOERR; + } + auto xattrValue = CreateUniquePtr(static_cast(xAttrSize) + 1); + xAttrSize = getxattr(path, key, xattrValue.get(), static_cast(xAttrSize)); + if (xAttrSize == -1) { + return errno; + } + xattrValue[xAttrSize] = '\0'; + *result = std::string(xattrValue.get()); + return ERRNO_NOERR; +} + +FsResult XattrCore::DoSetXattr(const string &path, const string &key, const string &value) +{ + if (IsIllegalXattr(key.c_str(), value.c_str())) { + HILOGE("Invalid xattr value"); + return FsResult::Error(EINVAL); + } + if (setxattr(path.c_str(), key.c_str(), value.c_str(), strnlen(value.c_str(), MAX_XATTR_SIZE), 0) < 0) { + HILOGE("setxattr fail, errno is %{public}d", errno); + return FsResult::Error(errno); + } + return FsResult::Success(); +} + +FsResult XattrCore::DoGetXattr(const string &path, const string &key) +{ + auto result = make_shared(); + int32_t ret = GetXattrCore(path.c_str(), key.c_str(), result); + if (ret != ERRNO_NOERR) { + HILOGE("Invalid getxattr"); + return FsResult::Error(ret); + } + return FsResult::Success(move(*result)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/xattr_core.h b/interfaces/kits/js/src/mod_fs/properties/xattr_core.h new file mode 100644 index 0000000000000000000000000000000000000000..71ca376e91e7ff8b649fcbc4f6ad327f0b8a7bf2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/xattr_core.h @@ -0,0 +1,35 @@ +/* + * 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_XATTR_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_XATTR_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +class XattrCore final { +public: + static FsResult DoSetXattr(const string &path, const string &key, const string &value); + static FsResult DoGetXattr(const string &path, const string &key); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_XATTR_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_hash/ani/bind_function_class.cpp index 5ab549948f7657e1acd6b2f77b61051469aabf57..d8fd4c556d816865cb5ea30aac157723b8572350 100644 --- a/interfaces/kits/js/src/mod_hash/ani/bind_function_class.cpp +++ b/interfaces/kits/js/src/mod_hash/ani/bind_function_class.cpp @@ -17,6 +17,7 @@ #include "ani_signature.h" #include "bind_function.h" #include "hash_ani.h" +#include "hashstream_ani.h" using namespace OHOS::FileManagement::ModuleFileIO::ANI; using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; @@ -57,4 +58,4 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) *result = ANI_VERSION_1; return ANI_OK; -} \ No newline at end of file +} diff --git a/interfaces/kits/js/src/mod_hash/ani/ets/@ohos.file.hash.ets b/interfaces/kits/js/src/mod_hash/ani/ets/@ohos.file.hash.ets index 7b825ee1468b27f428eff144b633d65fe6602dd6..56e07f441f89778566a7e2596a097a4e317ea7c5 100644 --- a/interfaces/kits/js/src/mod_hash/ani/ets/@ohos.file.hash.ets +++ b/interfaces/kits/js/src/mod_hash/ani/ets/@ohos.file.hash.ets @@ -14,7 +14,6 @@ */ import { BusinessError, AsyncCallback } from '@ohos.base'; -// import stream from '@ohos.util.stream'; export default namespace hash { export function hash(path: string, algorithm: string): Promise { @@ -23,8 +22,8 @@ export default namespace hash { promise.then((ret: NullishType): void => { let res = ret as string; resolve(res); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -36,51 +35,10 @@ export default namespace hash { e.code = 0; let res = ret as string; callback(e, res); - }).catch((e: BusinessError): void => { - callback(e, ""); + }).catch((e: Error): void => { + callback(e as BusinessError, ""); }); } - - // export function createHash(algorithm: string): HashStream { - // return new HashStream(algorithm); - // } - - // export class HashStream extends stream.Transform { - // hs: hash.HashStream; - // hashBuf?: ArrayBuffer; - - // constructor(algorithm: string) { - // super(); - // this.hs = new hash.HashStream(algorithm); - // } - - // digest(): string { - // return this.hs.digest(); - // } - - // update(data: ArrayBuffer): void { - // this.hs.update(data); - // } - - // doTransform(chunk: string, encoding: string, callback: () => void): void { - // let charCodes: number[] = []; - // for (let i = 0; i < chunk.length; i++) { - // charCodes = [...charCodes, chunk.charCodeAt(i)]; - // } - // const buf = new Uint8Array(charCodes).buffer; - // this.hs.update((buf as ArrayBuffer)); - // this.push(chunk); - // callback(); - // } - - // doWrite(chunk: string | Uint8Array, encoding: string, callback: () => void): void { - // callback(); - // } - - // doFlush(callback: () => void): void { - // callback(); - // } - // } } class HashImpl { diff --git a/interfaces/kits/js/src/mod_hash/class_hashstream/ani/hashstream_ani.cpp b/interfaces/kits/js/src/mod_hash/class_hashstream/ani/hashstream_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cac067b37b5ce8366ea1cfcbc7f5ff16d39e13a7 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/class_hashstream/ani/hashstream_ani.cpp @@ -0,0 +1,123 @@ +/* + * 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 "hashstream_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "hs_hashstream.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +namespace fs = std::filesystem; +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; + +HsHashStream *Unwrap(ani_env *env, ani_object object) +{ + ani_long nativePtr; + auto ret = env->Object_GetFieldByName_Long(object, "nativePtr", &nativePtr); + if (ret != ANI_OK) { + HILOGE("Unwrap hashstream err: %{public}d", ret); + return nullptr; + } + uintptr_t ptrValue = static_cast(nativePtr); + HsHashStream *hashStream = reinterpret_cast(ptrValue); + return hashStream; +} + +void HashStreamAni::Update(ani_env *env, [[maybe_unused]] ani_object object, ani_arraybuffer buffer) +{ + auto hashStream = Unwrap(env, object); + if (hashStream == nullptr) { + HILOGE("Cannot unwrap hashStream!"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [succ, arrayBuffer] = TypeConverter::ToArrayBuffer(env, buffer); + if (!succ) { + HILOGE("illegal array buffer"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto ret = hashStream->Update(arrayBuffer); + if (!ret.IsSuccess()) { + HILOGE("Cannot Update!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} + +ani_string HashStreamAni::Digest(ani_env *env, [[maybe_unused]] ani_object object) +{ + auto hashStream = Unwrap(env, object); + if (hashStream == nullptr) { + HILOGE("Cannot unwrap hashStream!"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto ret = hashStream->Digest(); + if (!ret.IsSuccess()) { + HILOGE("Cannot Digest!"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + + const auto &res = ret.GetData().value(); + auto [succ, result] = TypeConverter::ToAniString(env, res); + if (!succ) { + HILOGE("Convert result to ani string failed"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} + +void HashStreamAni::Constructor(ani_env *env, ani_object obj, ani_string alg) +{ + auto [succ, algorithm] = TypeConverter::ToUTF8String(env, alg); + if (!succ) { + HILOGE("Invalid alg"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto ret = HsHashStream::Constructor(algorithm); + if (!ret.IsSuccess()) { + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } + + if (ANI_OK != + env->Object_SetFieldByName_Long(obj, "nativePtr", reinterpret_cast(ret.GetData().value()))) { + HILOGE("Failed to wrap entity for obj HashStream"); + ErrorHandler::Throw(env, EIO); + return; + } +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/class_hashstream/ani/hashstream_ani.h b/interfaces/kits/js/src/mod_hash/class_hashstream/ani/hashstream_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..c5f98974ea2d5b59ee5eb107fb631857c7e411ee --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/class_hashstream/ani/hashstream_ani.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_HASH_HASHSTREAM_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_HASH_HASHSTREAM_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class HashStreamAni final { +public: + static void Constructor(ani_env *env, ani_object obj, ani_string alg); + static ani_string Digest(ani_env *env, [[maybe_unused]] ani_object object); + static void Update(ani_env *env, [[maybe_unused]] ani_object object, ani_arraybuffer buffer); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_HASH_HASHSTREAM_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream.cpp b/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b03eb2b15e9f1ed4e8c34f50095039b56808e11e --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream.cpp @@ -0,0 +1,161 @@ +/* + * 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 "hs_hashstream.h" + +#include +#include + +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static HASH_ALGORITHM_TYPE GetHashAlgorithm(const string &alg) +{ + return (algorithmMaps.find(alg) != algorithmMaps.end()) ? algorithmMaps.at(alg) : HASH_ALGORITHM_TYPE_UNSUPPORTED; +} + +static string HashFinal(const unique_ptr &hashBuf, size_t hashLen) +{ + stringstream ss; + for (size_t i = 0; i < hashLen; ++i) { + const int hexPerByte = 2; + ss << std::uppercase << std::setfill('0') << std::setw(hexPerByte) << std::hex + << static_cast(hashBuf[i]); + } + + return ss.str(); +} + +tuple HsHashStream::GetHsEntity() +{ + if (!entity) { + return { false, nullptr }; + } + return { true, entity.get() }; +} + +FsResult HsHashStream::Update(ArrayBuffer &buffer) +{ + auto [succ, hsEntity] = GetHsEntity(); + if (!succ) { + HILOGE("Failed to get entity of HashStream"); + return FsResult::Error(EIO); + } + + switch (hsEntity->algType) { + case HASH_ALGORITHM_TYPE_MD5: + MD5_Update(&hsEntity->md5Ctx, buffer.buf, buffer.length); + break; + case HASH_ALGORITHM_TYPE_SHA1: + SHA1_Update(&hsEntity->shaCtx, buffer.buf, buffer.length); + break; + case HASH_ALGORITHM_TYPE_SHA256: + SHA256_Update(&hsEntity->sha256Ctx, buffer.buf, buffer.length); + break; + default: + break; + } + + return FsResult::Success(); +} + +FsResult HsHashStream::Digest() +{ + auto [succ, hsEntity] = GetHsEntity(); + if (!succ) { + HILOGE("Failed to get entity of HashStream"); + return FsResult::Error(EIO); + } + + string digestStr; + switch (hsEntity->algType) { + case HASH_ALGORITHM_TYPE_MD5: { + auto res = make_unique(MD5_DIGEST_LENGTH); + MD5_Final(res.get(), &hsEntity->md5Ctx); + digestStr = HashFinal(res, MD5_DIGEST_LENGTH); + break; + } + case HASH_ALGORITHM_TYPE_SHA1: { + auto res = make_unique(SHA_DIGEST_LENGTH); + SHA1_Final(res.get(), &hsEntity->shaCtx); + digestStr = HashFinal(res, SHA_DIGEST_LENGTH); + break; + } + case HASH_ALGORITHM_TYPE_SHA256: { + auto res = make_unique(SHA256_DIGEST_LENGTH); + SHA256_Final(res.get(), &hsEntity->sha256Ctx); + digestStr = HashFinal(res, SHA256_DIGEST_LENGTH); + break; + } + default: + break; + } + return FsResult::Success(digestStr); +} + +FsResult HsHashStream::Constructor(string alg) +{ + HASH_ALGORITHM_TYPE algType = GetHashAlgorithm(alg); + if (algType == HASH_ALGORITHM_TYPE_UNSUPPORTED) { + HILOGE("algType is not found."); + return FsResult::Error(EINVAL); + } + + HsHashStreamEntity *rawPtr = new (std::nothrow) HsHashStreamEntity(); + if (rawPtr == nullptr) { + HILOGE("Failed to request heap memory."); + return FsResult::Error(ENOMEM); + } + std::unique_ptr hsEntity(rawPtr); + hsEntity->algType = algType; + + switch (algType) { + case HASH_ALGORITHM_TYPE_MD5: { + MD5_CTX ctx; + MD5_Init(&ctx); + hsEntity->md5Ctx = ctx; + break; + } + case HASH_ALGORITHM_TYPE_SHA1: { + SHA_CTX ctx; + SHA1_Init(&ctx); + hsEntity->shaCtx = ctx; + break; + } + case HASH_ALGORITHM_TYPE_SHA256: { + SHA256_CTX ctx; + SHA256_Init(&ctx); + hsEntity->sha256Ctx = ctx; + break; + } + default: + break; + } + + HsHashStream *hsStreamPtr = new HsHashStream(move(hsEntity)); + if (hsStreamPtr == nullptr) { + HILOGE("Failed to create HsHashStream object on heap."); + return FsResult::Error(ENOMEM); + } + + return FsResult::Success(move(hsStreamPtr)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream.h b/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream.h new file mode 100644 index 0000000000000000000000000000000000000000..b39b86fb2998afc82c15d7fd94acfd66b1d61299 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream.h @@ -0,0 +1,46 @@ +/* + * 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_HASH_CLASS_HASHSTREAM_HS_HASHSTREAM_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_HASH_CLASS_HASHSTREAM_HS_HASHSTREAM_CORE_H + +#include +#include "filemgmt_libfs.h" +#include "fs_utils.h" +#include "hs_hashstream_entity.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; + +class HsHashStream { +public: + HsHashStream(const HsHashStream &) = delete; + HsHashStream &operator=(const HsHashStream &) = delete; + + tuple GetHsEntity(); + FsResult Update(ArrayBuffer &buffer); + FsResult Digest(); + + static FsResult Constructor(string alg); + ~HsHashStream() = default; + +private: + unique_ptr entity; + explicit HsHashStream(unique_ptr entity) : entity(move(entity)) {} +}; + +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // INTERFACES_KITS_JS_SRC_MOD_HASH_CLASS_HASHSTREAM_HS_HASHSTREAM_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream_entity.h b/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..de1700cadb3121bc80cd58cd57b1aa1451affab3 --- /dev/null +++ b/interfaces/kits/js/src/mod_hash/class_hashstream/hs_hashstream_entity.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_HASH_CLASS_HASHSTREAM_HS_HASHSTREAM_ENTITY_H +#define INTERFACES_KITS_JS_SRC_MOD_HASH_CLASS_HASHSTREAM_HS_HASHSTREAM_ENTITY_H + +#include +#include +#include + +#include "hash_core.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +struct HsHashStreamEntity { + MD5_CTX md5Ctx; + SHA_CTX shaCtx; + SHA256_CTX sha256Ctx; + HASH_ALGORITHM_TYPE algType = HASH_ALGORITHM_TYPE_UNSUPPORTED; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_HASH_CLASS_HASHSTREAM_HS_HASHSTREAM_ENTITY_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_securitylabel/ani/ets/@ohos.file.securityLabel.ets b/interfaces/kits/js/src/mod_securitylabel/ani/ets/@ohos.file.securityLabel.ets index 06e659dc275ae1890e009c02fc830bd8e766dbea..4f81cef3d8fc0f2c702d436507c7493149fb2cfb 100644 --- a/interfaces/kits/js/src/mod_securitylabel/ani/ets/@ohos.file.securityLabel.ets +++ b/interfaces/kits/js/src/mod_securitylabel/ani/ets/@ohos.file.securityLabel.ets @@ -23,8 +23,8 @@ namespace securityLabel { let promise = taskpool.execute((path: string, type: DataLevel): void => SecurityLabelImpl.setSecurityLabelSync(path, type), path, type); promise.then((ret: NullishType): void => { resolve(undefined); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -35,8 +35,8 @@ namespace securityLabel { let e = new BusinessError(); e.code = 0; callback(e, undefined); - }).catch((e: BusinessError): void => { - callback(e, undefined); + }).catch((e: Error): void => { + callback(e as BusinessError, undefined); }); } @@ -50,8 +50,8 @@ namespace securityLabel { promise.then((ret: NullishType): void => { let r = ret as string; resolve(r); - }).catch((e: BusinessError): void => { - reject(e); + }).catch((e: Error): void => { + reject(e as BusinessError); }); }); } @@ -63,8 +63,8 @@ namespace securityLabel { e.code = 0; let r = ret as string; callback(e, r); - }).catch((e: BusinessError): void => { - callback(e, ""); + }).catch((e: Error): void => { + callback(e as BusinessError, ""); }); } diff --git a/interfaces/kits/js/src/mod_statvfs/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_statvfs/ani/bind_function_class.cpp new file mode 100644 index 0000000000000000000000000000000000000000..33782a3d10d71c8cde2bfce292e4caddfb0637ff --- /dev/null +++ b/interfaces/kits/js/src/mod_statvfs/ani/bind_function_class.cpp @@ -0,0 +1,62 @@ +/* + * 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 "ani_signature.h" +#include "bind_function.h" +#include "statvfs_ani.h" + +using namespace OHOS::FileManagement::ModuleFileIO::ANI; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +static ani_status BindStaticMethods(ani_env *env) +{ + auto classDesc = Impl::StatvfsImpl::classDesc.c_str(); + + std::array methods = { + ani_native_function { "getFreeSizeSync", nullptr, reinterpret_cast(StatvfsAni::GetFreeSizeSync) }, + ani_native_function { "getTotalSizeSync", nullptr, reinterpret_cast(StatvfsAni::GetTotalSizeSync) }, + }; + return BindClass(env, classDesc, methods); +} + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + if (vm == nullptr) { + HILOGE("Invalid parameter vm"); + return ANI_INVALID_ARGS; + } + + if (result == nullptr) { + HILOGE("Invalid parameter result"); + return ANI_INVALID_ARGS; + } + + ani_env *env; + ani_status status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + HILOGE("Invalid ani version!"); + return ANI_INVALID_VERSION; + } + + if ((status = BindStaticMethods(env)) != ANI_OK) { + HILOGE("Cannot bind native static methods for statvfs!"); + return status; + }; + + *result = ANI_VERSION_1; + return ANI_OK; +} \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_statvfs/ani/ets/@ohos.file.statvfs.ets b/interfaces/kits/js/src/mod_statvfs/ani/ets/@ohos.file.statvfs.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3c569c80543f18810ca4e4c0e31a8ff0fe81b7a --- /dev/null +++ b/interfaces/kits/js/src/mod_statvfs/ani/ets/@ohos.file.statvfs.ets @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BusinessError, AsyncCallback } from '@ohos.base'; + +namespace statfs { + export function getFreeSizeSync(path: string): number { + return StatvfsImpl.getFreeSizeSync(path); + } + + export function getFreeSize(path: string): Promise { + return new Promise((resolve: (result: number) => void, reject: (e: BusinessError) => void): void => { + let promise = taskpool.execute(StatvfsImpl.getFreeSizeSync, path); + promise.then((ret: NullishType): void => { + let result = ret as number + resolve(result); + }).catch((e: Error): void => { + reject(e as BusinessError); + }); + }); + } + + export function getFreeSize(path: string, callback: AsyncCallback): void { + let promise = taskpool.execute(StatvfsImpl.getFreeSizeSync, path); + promise.then((ret: NullishType): void => { + let e = new BusinessError(); + e.code = 0; + let result = ret as number; + callback(e, result); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); + }); + } + + export function getTotalSizeSync(path: string): number { + return StatvfsImpl.getTotalSizeSync(path); + } + + export function getTotalSize(path: string): Promise { + return new Promise((resolve: (result: number) => void, reject: (e: BusinessError) => void): void => { + let promise = taskpool.execute(StatvfsImpl.getTotalSizeSync, path); + promise.then((ret: NullishType): void => { + let result = ret as number + resolve(result); + }).catch((e: Error): void => { + reject(e as BusinessError); + }); + }); + } + + export function getTotalSize(path: string, callback: AsyncCallback): void { + let promise = taskpool.execute(StatvfsImpl.getTotalSizeSync, path); + promise.then((ret: NullishType): void => { + let e = new BusinessError(); + e.code = 0; + let result = ret as number; + callback(e, result); + }).catch((e: Error): void => { + callback(e as BusinessError, 0); + }); + } +} + +export default statfs; + +class StatvfsImpl { + + static { + loadLibrary("ani_file_statvfs"); + } + + static native getFreeSizeSync(path: string): number; + static native getTotalSizeSync(path: string): number; +} diff --git a/interfaces/kits/js/src/mod_statvfs/ani/statvfs_ani.cpp b/interfaces/kits/js/src/mod_statvfs/ani/statvfs_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..337b78f84341de0d691d1a3b49b3ebb827069bbd --- /dev/null +++ b/interfaces/kits/js/src/mod_statvfs/ani/statvfs_ani.cpp @@ -0,0 +1,75 @@ +/* + * 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 "statvfs_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "statvfs_core.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::ModuleStatvfs; + +ani_double StatvfsAni::GetFreeSizeSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path) +{ + auto [succPath, srcPath] = TypeConverter::ToUTF8String(env, path); + if (!succPath) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return 0; + } + + auto ret = StatvfsCore::DoGetFreeSize(srcPath); + if (!ret.IsSuccess()) { + HILOGE("Get freesize failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return 0; + } + + return static_cast(ret.GetData().value()); +} + +ani_double StatvfsAni::GetTotalSizeSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path) +{ + auto [succPath, srcPath] = TypeConverter::ToUTF8String(env, path); + if (!succPath) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return 0; + } + + auto ret = StatvfsCore::DoGetTotalSize(srcPath); + if (!ret.IsSuccess()) { + HILOGE("Get totalsize failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return 0; + } + + return static_cast(ret.GetData().value()); +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_statvfs/ani/statvfs_ani.h b/interfaces/kits/js/src/mod_statvfs/ani/statvfs_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..1eaf5081fdaf1c43002634d1e70e7face2f3673a --- /dev/null +++ b/interfaces/kits/js/src/mod_statvfs/ani/statvfs_ani.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_STATVFS_ANI_STATVFS_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_STATVFS_ANI_STATVFS_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class StatvfsAni final { +public: + static ani_double GetFreeSizeSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path); + static ani_double GetTotalSizeSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_STATVFS_ANI_STATVFS_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_statvfs/statvfs_core.cpp b/interfaces/kits/js/src/mod_statvfs/statvfs_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a9aa9db682784dcadb84e1510f6cca574ff90bf --- /dev/null +++ b/interfaces/kits/js/src/mod_statvfs/statvfs_core.cpp @@ -0,0 +1,52 @@ +/* + * 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 "statvfs_core.h" + +#include +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleStatvfs { +using namespace std; + +FsResult StatvfsCore::DoGetFreeSize(const string &path) +{ + struct statvfs diskInfo; + int ret = statvfs(path.c_str(), &diskInfo); + if (ret != 0) { + return FsResult::Error(errno); + } + unsigned long long freeSize = static_cast(diskInfo.f_bsize) * + static_cast(diskInfo.f_bfree); + return FsResult::Success(static_cast(freeSize)); +} + +FsResult StatvfsCore::DoGetTotalSize(const string &path) +{ + struct statvfs diskInfo; + int ret = statvfs(path.c_str(), &diskInfo); + if (ret != 0) { + return FsResult::Error(errno); + } + unsigned long long totalSize = static_cast(diskInfo.f_bsize) * + static_cast(diskInfo.f_blocks); + return FsResult::Success(static_cast(totalSize)); +} + +} // namespace ModuleStatfs +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_statvfs/statvfs_core.h b/interfaces/kits/js/src/mod_statvfs/statvfs_core.h new file mode 100644 index 0000000000000000000000000000000000000000..24817f3eb8a6cdb91c7604b74ba28eea33e711e1 --- /dev/null +++ b/interfaces/kits/js/src/mod_statvfs/statvfs_core.h @@ -0,0 +1,35 @@ +/* + * 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_STATVFS_STATVFS_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_STATVFS_STATVFS_CORE_H + +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleStatvfs { +using namespace ModuleFileIO; + +class StatvfsCore final { +public: + static FsResult DoGetFreeSize(const string &path); + static FsResult DoGetTotalSize(const string &path); +}; + +} // namespace ModuleStatvfs +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_STATVFS_STATVFS_CORE_H \ No newline at end of file diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index c6df1457ce86172af3a32e861737248541f9e527..9a3e2915ec3f109a57fc3638b5b85cec8f2c784f 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -19,10 +19,12 @@ group("file_api_unittest") { "class_atomicfile:class_atomicfile_test", "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", "js:ani_file_securitylabel_test", + "js:ani_file_statvfs_test", "js:napi_file_fs_test", "remote_uri:remote_uri_test", "task_signal:task_signal_test", diff --git a/interfaces/test/unittest/filemgmt_libn_test/include/napi_mock.h b/interfaces/test/unittest/filemgmt_libn_test/include/napi_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..1c5a4d1c48ee207eee17bc40c5c3aa49cad0244e --- /dev/null +++ b/interfaces/test/unittest/filemgmt_libn_test/include/napi_mock.h @@ -0,0 +1,114 @@ +/* + * 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_FILEMGMT_LIBN_TEST_INCLUDE_NAPI_MOCK_H +#define INTERFACES_TEST_UNITTEST_FILEMGMT_LIBN_TEST_INCLUDE_NAPI_MOCK_H + +#pragma once +#include +#include "n_napi.h" + +namespace OHOS { +namespace FileManagement { +namespace LibN { +namespace Test { + +class INapiMock { +public: + virtual ~INapiMock() = default; + + virtual napi_status napi_define_class(napi_env env, const char *name, size_t length, napi_callback constructor, + void *data, size_t property_count, const napi_property_descriptor *properties, napi_value *result) = 0; + + virtual napi_status napi_create_reference( + napi_env env, napi_value value, uint32_t initial_refcount, napi_ref *result) = 0; + + virtual napi_status napi_add_env_cleanup_hook(napi_env env, void (*fun)(void *arg), void *arg) = 0; + + virtual napi_status napi_delete_reference(napi_env env, napi_ref ref) = 0; + + virtual napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value *result) = 0; + + virtual napi_status napi_new_instance( + napi_env env, napi_value constructor, size_t argc, const napi_value *argv, napi_value *result) = 0; + + virtual napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) = 0; + + virtual napi_status napi_wrap(napi_env env, napi_value js_object, void *native_object, napi_finalize finalize_cb, + void *finalize_hint, napi_ref *result) = 0; + + virtual napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result) = 0; +}; + +class NapiMock : public INapiMock { +public: + MOCK_METHOD(napi_status, napi_define_class, + (napi_env, const char *, size_t, napi_callback, void *, size_t, const napi_property_descriptor *, napi_value *), + (override)); + + MOCK_METHOD(napi_status, napi_create_reference, (napi_env, napi_value, uint32_t, napi_ref *), (override)); + + MOCK_METHOD(napi_status, napi_add_env_cleanup_hook, (napi_env env, void (*fun)(void *arg), void *arg), (override)); + + MOCK_METHOD(napi_status, napi_delete_reference, (napi_env env, napi_ref ref), (override)); + + MOCK_METHOD(napi_status, napi_get_reference_value, (napi_env env, napi_ref ref, napi_value *result), (override)); + + MOCK_METHOD(napi_status, napi_new_instance, + (napi_env env, napi_value constructor, size_t argc, const napi_value *argv, napi_value *result), (override)); + + MOCK_METHOD(napi_status, napi_unwrap, (napi_env env, napi_value js_object, void **result), (override)); + + MOCK_METHOD(napi_status, napi_wrap, + (napi_env env, napi_value js_object, void *native_object, napi_finalize finalize_cb, void *finalize_hint, + napi_ref *result), + (override)); + + MOCK_METHOD(napi_status, napi_remove_wrap, (napi_env env, napi_value js_object, void **result), (override)); +}; + +NapiMock &GetNapiMock(); +void SetNapiMock(NapiMock *mock); +void ResetNapiMock(); + +class ScopedNapiMock { +public: + explicit ScopedNapiMock(NapiMock *mock) : mock_(mock) + { + SetNapiMock(mock_); + } + + ~ScopedNapiMock() + { + ResetNapiMock(); + } + + NapiMock &GetMock() + { + return *mock_; + } + + ScopedNapiMock(const ScopedNapiMock &) = delete; + ScopedNapiMock &operator=(const ScopedNapiMock &) = delete; + +private: + NapiMock *mock_; +}; + +} // namespace Test +} // namespace LibN +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_TEST_UNITTEST_FILEMGMT_LIBN_TEST_INCLUDE_NAPI_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/filemgmt_libn_test/src/napi_mock.cpp b/interfaces/test/unittest/filemgmt_libn_test/src/napi_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..096ca426bb12650b86ba16c2b8d3e138496babe1 --- /dev/null +++ b/interfaces/test/unittest/filemgmt_libn_test/src/napi_mock.cpp @@ -0,0 +1,106 @@ +/* + * 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 "napi_mock.h" + +#include + +namespace OHOS { +namespace FileManagement { +namespace LibN { +namespace Test { + +namespace { +std::mutex g_mockMutex; +NapiMock *g_currentMock = nullptr; +NapiMock g_defaultMock; +} // namespace + +NapiMock &GetNapiMock() +{ + std::lock_guard lock(g_mockMutex); + return g_currentMock ? *g_currentMock : g_defaultMock; +} + +void SetNapiMock(NapiMock *mock) +{ + std::lock_guard lock(g_mockMutex); + g_currentMock = mock; +} + +void ResetNapiMock() +{ + SetNapiMock(nullptr); +} + +} // namespace Test +} // namespace LibN +} // namespace FileManagement +} // namespace OHOS + +#ifdef ENABLE_NAPI_MOCK +extern "C" { +using namespace OHOS::FileManagement::LibN::Test; + +napi_status napi_define_class(napi_env env, const char *name, size_t length, napi_callback constructor, void *data, + size_t property_count, const napi_property_descriptor *properties, napi_value *result) +{ + return GetNapiMock().napi_define_class(env, name, length, constructor, data, property_count, properties, result); +} + +napi_status napi_create_reference(napi_env env, napi_value value, uint32_t initial_refcount, napi_ref *result) +{ + return GetNapiMock().napi_create_reference(env, value, initial_refcount, result); +} + +napi_status napi_add_env_cleanup_hook(napi_env env, void (*fun)(void *arg), void *arg) +{ + return GetNapiMock().napi_add_env_cleanup_hook(env, fun, arg); +} + +napi_status napi_delete_reference(napi_env env, napi_ref ref) +{ + return GetNapiMock().napi_delete_reference(env, ref); +} + +napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value *result) +{ + return GetNapiMock().napi_get_reference_value(env, ref, result); +} + +napi_status napi_new_instance( + napi_env env, napi_value constructor, size_t argc, const napi_value *argv, napi_value *result) +{ + return GetNapiMock().napi_new_instance(env, constructor, argc, argv, result); +} + +napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) +{ + return GetNapiMock().napi_unwrap(env, js_object, result); +} + +napi_status napi_wrap(napi_env env, napi_value js_object, void *native_object, napi_finalize finalize_cb, + void *finalize_hint, napi_ref *result) +{ + return GetNapiMock().napi_wrap(env, js_object, native_object, finalize_cb, finalize_hint, result); +} + +napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result) +{ + return GetNapiMock().napi_remove_wrap(env, js_object, result); +} + +} // extern "C" +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index dbef98d6291e44383c57fe357b5f57fbd6e923fa..af69f199636ad31a32926f03f38f7fbef8838d1c 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -14,59 +14,46 @@ import("//build/test.gni") import("//foundation/filemanagement/file_api/file_api.gni") -ohos_unittest("ani_file_fs_mock_test") { +ohos_unittest("ani_file_environment_test") { branch_protector_ret = "pac_ret" testonly = true module_out_path = "file_api/file_api" - include_dirs = [ - "${file_api_path}/interfaces/kits/js/src/mod_fs/class_file", - "${file_api_path}/interfaces/kits/js/src/mod_fs/class_stat", - "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", - "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock", + "${src_path}/mod_environment", + "${src_path}/mod_environment/ani", + "${file_api_path}/interfaces/test/unittest/js/mod_environment/mock", ] sources = [ - "mod_fs/class_file/fs_file_mock_test.cpp", - "mod_fs/class_stat/fs_stat_mock_test.cpp", - "mod_fs/properties/access_core_mock_test.cpp", - "mod_fs/properties/copy_file_core_mock_test.cpp", - "mod_fs/properties/mkdir_core_mock_test.cpp", - "mod_fs/properties/mock/system_mock.cpp", - "mod_fs/properties/mock/uv_fs_mock.cpp", - "mod_fs/properties/move_core_mock_test.cpp", - "mod_fs/properties/open_core_mock_test.cpp", - "mod_fs/properties/read_core_mock_test.cpp", - "mod_fs/properties/stat_core_mock_test.cpp", - "mod_fs/properties/truncate_core_mock_test.cpp", - "mod_fs/properties/unlink_core_mock_test.cpp", - "mod_fs/properties/write_core_mock_test.cpp", + "mod_environment/environment_core_mock_test.cpp", + "mod_environment/mock/accesstoken_kit_mock.cpp", + "mod_environment/mock/ipc_skeleton_mock.cpp", + "mod_environment/mock/parameter_mock.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", + "${file_api_path}/interfaces/kits/js:ani_file_environment", "${utils_path}/filemgmt_libfs:filemgmt_libfs", "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", ] external_deps = [ - "ability_runtime:ability_manager", - "app_file_service:fileuri_native", - "c_utils:utils", + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", + "init:libbegetutil", "ipc:ipc_core", "libuv:uv", + "openssl:libcrypto_shared", + "os_account:os_account_innerkits", + "runtime_core:ani", + "runtime_core:libarkruntime", ] defines = [ "private=public" ] - - use_exceptions = true } ohos_unittest("ani_file_fs_test") { @@ -75,8 +62,6 @@ ohos_unittest("ani_file_fs_test") { module_out_path = "file_api/file_api" - resource_config_file = "../resource/ohos_test.xml" - include_dirs = [ "${file_api_path}/interfaces/kits/js/src/mod_fs/class_atomicfile", "${file_api_path}/interfaces/kits/js/src/mod_fs/class_file", @@ -86,23 +71,42 @@ 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 = [ + "mod_fs/class_atomicfile/fs_atomicfile_test.cpp", "mod_fs/class_file/fs_file_test.cpp", + "mod_fs/class_randomaccessfile/fs_randomaccessfile_test.cpp", + "mod_fs/class_readeriterator/fs_reader_iterator_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", "mod_fs/properties/copy_file_core_test.cpp", + "mod_fs/properties/create_randomaccessfile_core_test.cpp", + "mod_fs/properties/create_stream_core_test.cpp", + "mod_fs/properties/dup_core_test.cpp", + "mod_fs/properties/fdopen_stream_core_test.cpp", "mod_fs/properties/listfile_core_test.cpp", + "mod_fs/properties/lseek_core_test.cpp", + "mod_fs/properties/lstat_core_test.cpp", "mod_fs/properties/move_core_test.cpp", + "mod_fs/properties/movedir_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/stat_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", + "mod_fs/properties/xattr_core_test.cpp", ] deps = [ @@ -118,6 +122,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", @@ -125,8 +131,98 @@ ohos_unittest("ani_file_fs_test") { ] defines = [ "private=public" ] +} - use_exceptions = true +ohos_unittest("ani_file_fs_mock_test") { + branch_protector_ret = "pac_ret" + testonly = true + + module_out_path = "file_api/file_api" + + include_dirs = [ + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_atomicfile", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_file", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_randomaccessfile", + "${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/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", + ] + + sources = [ + "mod_fs/class_file/fs_file_mock_test.cpp", + "mod_fs/class_randomaccessfile/fs_randomaccessfile_mock_test.cpp", + "mod_fs/class_readeriterator/fs_reader_iterator_mock_test.cpp", + "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/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/access_core_mock_test.cpp", + "mod_fs/properties/copy_core_mock_test.cpp", + "mod_fs/properties/copy_file_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/fsync_core_mock_test.cpp", + "mod_fs/properties/lstat_core_mock_test.cpp", + "mod_fs/properties/mkdir_core_mock_test.cpp", + "mod_fs/properties/mkdtemp_core_mock_test.cpp", + "mod_fs/properties/mock/system_mock.cpp", + "mod_fs/properties/mock/uv_fs_mock.cpp", + "mod_fs/properties/move_core_mock_test.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/rename_core_mock_test.cpp", + "mod_fs/properties/stat_core_mock_test.cpp", + "mod_fs/properties/symlink_core_mock_test.cpp", + "mod_fs/properties/trans_listener_mock_test.cpp", + "mod_fs/properties/unlink_core_mock_test.cpp", + "mod_fs/properties/utimes_core_mock_test.cpp", + "mod_fs/properties/watcher_core_mock_test.cpp", + "mod_fs/properties/xattr_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", + ] + + external_deps = [ + "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", + "ipc:ipc_core", + "libuv:uv", + ] + + libs = [ "dl" ] + + defines = [ + "ENABLE_DISTRIBUTED_FILE_MOCK", + "private=public", + ] } ohos_unittest("ani_file_hash_test") { @@ -154,8 +250,6 @@ ohos_unittest("ani_file_hash_test") { "hilog:libhilog", "libuv:uv", ] - - use_exceptions = true } ohos_unittest("ani_file_securitylabel_test") { @@ -165,7 +259,10 @@ ohos_unittest("ani_file_securitylabel_test") { sources = [ "mod_securitylabel/securitylabel_core_test.cpp" ] - include_dirs = [ "${file_api_path}/interfaces/kits/js/src/mod_securitylabel" ] + include_dirs = [ + "mock/libuv", + "${file_api_path}/interfaces/kits/js/src/mod_securitylabel", + ] deps = [ "${file_api_path}/interfaces/kits/js:ani_file_securitylabel", @@ -178,9 +275,35 @@ ohos_unittest("ani_file_securitylabel_test") { "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", + "libuv:uv", ] +} - use_exceptions = true +ohos_unittest("ani_file_statvfs_test") { + module_out_path = "file_api/file_api" + + resource_config_file = "../resource/ohos_test.xml" + + sources = [ "mod_statvfs/statvfs_core_test.cpp" ] + + include_dirs = [ + "mock/libuv", + "${file_api_path}/interfaces/kits/js/src/mod_statvfs", + ] + + deps = [ + "${file_api_path}/interfaces/kits/js:ani_file_statvfs", + "${utils_path}/filemgmt_libfs:filemgmt_libfs", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + ] + + external_deps = [ + "c_utils:utils", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "libuv:uv", + ] } ohos_unittest("napi_file_fs_test") { @@ -213,4 +336,4 @@ ohos_unittest("napi_file_fs_test") { defines = [ "private=public" ] use_exceptions = true -} \ No newline at end of file +} diff --git a/interfaces/test/unittest/js/mod_fs/class_file/fs_file_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_file/fs_file_mock_test.cpp index 0dcd0e963a7f43f21e8164972a3e0ec674dfc5c4..90cc1f29fd106e2b2727a9d0ab28e7bc0534308e 100644 --- a/interfaces/test/unittest/js/mod_fs/class_file/fs_file_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_file/fs_file_mock_test.cpp @@ -75,12 +75,12 @@ void FsFileMockTest::TearDown(void) } /** -* @tc.name: FsFileMockTest_GetPath_001 -* @tc.desc: Test function of GetPath() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetPath_001 + * @tc.desc: Test function of GetPath() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetPath_001, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetPath_001"; @@ -100,12 +100,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetPath_001, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_GetPath_002 -* @tc.desc: Test function of GetPath() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetPath_002 + * @tc.desc: Test function of GetPath() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetPath_002, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetPath_002"; @@ -119,12 +119,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetPath_002, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_GetName_003 -* @tc.desc: Test function of GetName() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetName_003 + * @tc.desc: Test function of GetName() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_003, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetName_003"; @@ -138,12 +138,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_003, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_GetName_004 -* @tc.desc: Test function of GetName() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetName_004 + * @tc.desc: Test function of GetName() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_004, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetName_004"; @@ -157,12 +157,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_004, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_GetParent_005 -* @tc.desc: Test function of GetParent() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetParent_005 + * @tc.desc: Test function of GetParent() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetParent_005, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetParent_005"; @@ -176,12 +176,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetParent_005, testing::ext::TestSize.Le } /** -* @tc.name: FsFileMockTest_GetName_006 -* @tc.desc: Test function of GetName() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetName_006 + * @tc.desc: Test function of GetName() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_006, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetName_006"; @@ -201,12 +201,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_006, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_GetParent_007 -* @tc.desc: Test function of GetParent() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetParent_007 + * @tc.desc: Test function of GetParent() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetParent_007, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetParent_007"; @@ -226,12 +226,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetParent_007, testing::ext::TestSize.Le } /** -* @tc.name: FsFileMockTest_GetName_008 -* @tc.desc: Test function of GetName() interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetName_008 + * @tc.desc: Test function of GetName() interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_008, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetName_008"; @@ -251,12 +251,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetName_008, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_GetParent_009 -* @tc.desc: Test function of GetParent() interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_GetParent_009 + * @tc.desc: Test function of GetParent() interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_GetParent_009, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_GetParent_009"; @@ -276,12 +276,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_GetParent_009, testing::ext::TestSize.Le } /** -* @tc.name: FsFileMockTest_Lock_010 -* @tc.desc: Test function of Lock() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_Lock_010 + * @tc.desc: Test function of Lock() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_Lock_010, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_Lock_010"; @@ -294,12 +294,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_Lock_010, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileMockTest_Lock_011 -* @tc.desc: Test function of Lock() interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_Lock_011 + * @tc.desc: Test function of Lock() interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_Lock_011, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_Lock_011"; @@ -312,12 +312,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_Lock_011, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileMockTest_TryLock_012 -* @tc.desc: Test function of TryLock() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_TryLock_012 + * @tc.desc: Test function of TryLock() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_TryLock_012, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_TryLock_012"; @@ -330,12 +330,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_TryLock_012, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_TryLock_013 -* @tc.desc: Test function of TryLock() interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_TryLock_013 + * @tc.desc: Test function of TryLock() interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_TryLock_013, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_TryLock_013"; @@ -348,12 +348,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_TryLock_013, testing::ext::TestSize.Leve } /** -* @tc.name: FsFileMockTest_UnLock_014 -* @tc.desc: Test function of UnLock() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_UnLock_014 + * @tc.desc: Test function of UnLock() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_UnLock_014, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_UnLock_014"; @@ -366,12 +366,12 @@ HWTEST_F(FsFileMockTest, FsFileMockTest_UnLock_014, testing::ext::TestSize.Level } /** -* @tc.name: FsFileMockTest_UnLock_015 -* @tc.desc: Test function of UnLock() interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileMockTest_UnLock_015 + * @tc.desc: Test function of UnLock() interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileMockTest, FsFileMockTest_UnLock_015, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileMockTest-begin FsFileMockTest_UnLock_015"; diff --git a/interfaces/test/unittest/js/mod_fs/class_file/fs_file_test.cpp b/interfaces/test/unittest/js/mod_fs/class_file/fs_file_test.cpp index 242d472ffe6fed6841812d3792601e06fc528194..e432f66f6109e8f96b668a2911b0842e34435beb 100644 --- a/interfaces/test/unittest/js/mod_fs/class_file/fs_file_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_file/fs_file_test.cpp @@ -29,8 +29,8 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); - std::unique_ptr fileEntity; - std::unique_ptr fsFile; + unique_ptr fileEntity; + unique_ptr fsFile; }; void FsFileTest::SetUpTestCase(void) @@ -47,13 +47,13 @@ void FsFileTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; - fileEntity = std::make_unique(); + fileEntity = make_unique(); const int fdValue = 3; const bool isClosed = false; - fileEntity->fd_ = std::make_unique(fdValue, isClosed); + fileEntity->fd_ = make_unique(fdValue, isClosed); fileEntity->path_ = "/data/test/file_test.txt"; fileEntity->uri_ = ""; - fsFile = std::make_unique(std::move(fileEntity)); + fsFile = make_unique(move(fileEntity)); } void FsFileTest::TearDown(void) @@ -62,12 +62,12 @@ void FsFileTest::TearDown(void) } /** -* @tc.name: FsFileTest_Constructor_001 -* @tc.desc: Test function of FsFile::Constructor() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_Constructor_001 + * @tc.desc: Test function of FsFile::Constructor() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_Constructor_001, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_Constructor_001"; @@ -79,12 +79,12 @@ HWTEST_F(FsFileTest, FsFileTest_Constructor_001, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetFD_002 -* @tc.desc: Test function of GetFD() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetFD_002 + * @tc.desc: Test function of GetFD() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetFD_002, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetFD_002"; @@ -96,17 +96,17 @@ HWTEST_F(FsFileTest, FsFileTest_GetFD_002, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetFD_003 -* @tc.desc: Test function of GetFD() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetFD_003 + * @tc.desc: Test function of GetFD() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetFD_003, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetFD_003"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->GetFD(); EXPECT_EQ(result.IsSuccess(), false); @@ -114,17 +114,17 @@ HWTEST_F(FsFileTest, FsFileTest_GetFD_003, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetPath_004 -* @tc.desc: Test function of GetPath() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetPath_004 + * @tc.desc: Test function of GetPath() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetPath_004, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetPath_004"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->GetPath(); EXPECT_EQ(result.IsSuccess(), false); @@ -132,17 +132,17 @@ HWTEST_F(FsFileTest, FsFileTest_GetPath_004, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetName_005 -* @tc.desc: Test function of GetName() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetName_005 + * @tc.desc: Test function of GetName() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetName_005, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetName_005"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->GetName(); EXPECT_EQ(result.IsSuccess(), false); @@ -150,17 +150,17 @@ HWTEST_F(FsFileTest, FsFileTest_GetName_005, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetParent_006 -* @tc.desc: Test function of GetParent() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetParent_006 + * @tc.desc: Test function of GetParent() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetParent_006, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetParent_006"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->GetParent(); EXPECT_EQ(result.IsSuccess(), false); @@ -168,17 +168,17 @@ HWTEST_F(FsFileTest, FsFileTest_GetParent_006, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_Lock_007 -* @tc.desc: Test function of Lock() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_Lock_007 + * @tc.desc: Test function of Lock() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_Lock_007, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_Lock_007"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->Lock(true); EXPECT_EQ(result.IsSuccess(), false); @@ -186,17 +186,17 @@ HWTEST_F(FsFileTest, FsFileTest_Lock_007, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_TryLock_008 -* @tc.desc: Test function of TryLock() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_TryLock_008 + * @tc.desc: Test function of TryLock() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_TryLock_008, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_TryLock_008"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->TryLock(true); EXPECT_EQ(result.IsSuccess(), false); @@ -204,17 +204,17 @@ HWTEST_F(FsFileTest, FsFileTest_TryLock_008, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_UnLock_009 -* @tc.desc: Test function of UnLock() interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_UnLock_009 + * @tc.desc: Test function of UnLock() interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_UnLock_009, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_UnLock_009"; - fsFile = std::make_unique(nullptr); + fsFile = make_unique(nullptr); auto result = fsFile->UnLock(); EXPECT_EQ(result.IsSuccess(), false); @@ -222,12 +222,12 @@ HWTEST_F(FsFileTest, FsFileTest_UnLock_009, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetName_010 -* @tc.desc: Test function of GetName() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetName_010 + * @tc.desc: Test function of GetName() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetName_010, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetName_010"; @@ -240,12 +240,12 @@ HWTEST_F(FsFileTest, FsFileTest_GetName_010, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetParent_011 -* @tc.desc: Test function of GetParent() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetParent_011 + * @tc.desc: Test function of GetParent() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetParent_011, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetParent_011"; @@ -258,12 +258,12 @@ HWTEST_F(FsFileTest, FsFileTest_GetParent_011, testing::ext::TestSize.Level1) } /** -* @tc.name: FsFileTest_GetPath_012 -* @tc.desc: Test function of GetPath() interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: FsFileTest_GetPath_012 + * @tc.desc: Test function of GetPath() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(FsFileTest, FsFileTest_GetPath_012, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "FsFileTest-begin FsFileTest_GetPath_012"; diff --git a/interfaces/test/unittest/js/mod_fs/class_stat/fs_stat_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_stat/fs_stat_mock_test.cpp index ea2e168d5195bee7530999b4e7c3c56b30cc8a98..2de8331e085893f1b1c0b6c862446bbcaa369cda 100644 --- a/interfaces/test/unittest/js/mod_fs/class_stat/fs_stat_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_stat/fs_stat_mock_test.cpp @@ -13,13 +13,13 @@ * limitations under the License. */ -#include "fs_stat.h" -#include "../properties/mock/system_mock.h" +#include +#include + #include "fs_stat_entity.h" +#include "fs_stat.h" #include "securec.h" - -#include -#include +#include "system_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; @@ -38,7 +38,7 @@ public: void FsStatMockTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; - sys = std::make_shared(); + sys = make_shared(); System::ins = sys; } @@ -70,17 +70,17 @@ HWTEST_F(FsStatMockTest, FsStatMockTest_GetLocation_001, testing::ext::TestSize. { GTEST_LOG_(INFO) << "FsStatMockTes-begin FsStatMockTest_GetLocation_001"; - std::unique_ptr statEntity; - std::unique_ptr fsStat; - statEntity = std::make_unique(); - statEntity->fileInfo_ = std::make_unique(); + unique_ptr statEntity; + unique_ptr fsStat; + statEntity = make_unique(); + statEntity->fileInfo_ = make_unique(); statEntity->fileInfo_->isPath = true; int length = 100; - string testPath = "/test/path"; - statEntity->fileInfo_->path = std::make_unique(length); + string testPath = "/test/stat_path"; + statEntity->fileInfo_->path = make_unique(length); strncpy_s(statEntity->fileInfo_->path.get(), length, testPath.c_str(), testPath.size()); statEntity->fileInfo_->path.get()[99] = '\0'; - fsStat = std::make_unique(std::move(statEntity)); + fsStat = make_unique(move(statEntity)); EXPECT_CALL(*sys, getxattr(_, _, _, _)).WillOnce(Return(1)); EXPECT_EQ(fsStat->GetLocation(), 1); @@ -99,15 +99,15 @@ HWTEST_F(FsStatMockTest, FsStatMockTest_GetLocation_002, testing::ext::TestSize. { GTEST_LOG_(INFO) << "FsStatMockTes-begin FsStatMockTest_GetLocation_002"; - std::unique_ptr statEntity; - std::unique_ptr fsStat; - statEntity = std::make_unique(); - statEntity->fileInfo_ = std::make_unique(); + unique_ptr statEntity; + unique_ptr fsStat; + statEntity = make_unique(); + statEntity->fileInfo_ = make_unique(); statEntity->fileInfo_->isPath = false; - const int fdValue = 3; + const int fdValue = 3; //模拟fd为3 const bool isClosed = false; - statEntity->fileInfo_->fdg = std::make_unique(fdValue, isClosed); - fsStat = std::make_unique(std::move(statEntity)); + statEntity->fileInfo_->fdg = make_unique(fdValue, isClosed); + fsStat = make_unique(move(statEntity)); EXPECT_CALL(*sys, fgetxattr(_, _, _, _)).WillOnce(Return(1)); EXPECT_EQ(fsStat->GetLocation(), 1); diff --git a/interfaces/test/unittest/js/mod_fs/class_stream/fs_stream_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_stream/fs_stream_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5641bd86b713d7302fa5440f65dfd19222bf82b0 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_stream/fs_stream_mock_test.cpp @@ -0,0 +1,191 @@ +/* + * 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 "c_mock.h" +#include "create_stream_core.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { +using namespace std; + +static const string g_streamFilePath = "/data/test/FsStreamCoreTest.txt"; + +class FsStreamMockTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + CMock::EnableMock(); + int32_t fd = open(g_streamFilePath.c_str(), CREATE | O_RDWR, 0644); + close(fd); + }; + static void TearDownTestCase() + { + CMock::DisableMock(); + rmdir(g_streamFilePath.c_str()); + }; + void SetUp() {}; + void TearDown() {}; +}; + +/** + * @tc.name: FsStreamSeekTest_0001 + * @tc.desc: Test function of Seek() interface for fail fseek. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamMockTest, FsStreamSeekTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamMockTest-begin FsStreamSeekTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(g_streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto mock_ = CMock::GetMock(); + EXPECT_CALL(*mock_, fseek(testing::_, testing::_, testing::_)).WillOnce(testing::Return(-1)); + + auto retSk = result->Seek(1); + EXPECT_FALSE(retSk.IsSuccess()); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamMockTest-end FsStreamSeekTest_0001"; +} + +/** + * @tc.name: FsStreamSeekTest_0002 + * @tc.desc: Test function of Seek() interface for fail ftell. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamMockTest, FsStreamSeekTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamMockTest-begin FsStreamSeekTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(g_streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto mock_ = CMock::GetMock(); + EXPECT_CALL(*mock_, fseek(testing::_, testing::_, testing::_)).WillOnce(testing::Return(0)); + EXPECT_CALL(*mock_, ftell(testing::_)).WillOnce(testing::Return(-1)); + + auto retSk = result->Seek(1); + EXPECT_FALSE(retSk.IsSuccess()); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamMockTest-end FsStreamSeekTest_0002"; +} + +/** + * @tc.name: FsStreamWriteTest_0001 + * @tc.desc: Test function of Write() interface for string fail fseek. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamMockTest, FsStreamWriteTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamMockTest-begin FsStreamWriteTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(g_streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto mock_ = CMock::GetMock(); + EXPECT_CALL(*mock_, fseek(testing::_, testing::_, testing::_)).WillOnce(testing::Return(-1)); + + WriteOptions opt; + opt.offset = 5; + auto retWr = result->Write("FsStreamWriteTest_0001", opt); + EXPECT_FALSE(retWr.IsSuccess()); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamMockTest-end FsStreamWriteTest_0001"; +} + +/** + * @tc.name: FsStreamWriteTest_0002 + * @tc.desc: Test function of Write() interface for ArrayBuffer fail fseek. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamMockTest, FsStreamWriteTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamMockTest-begin FsStreamWriteTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(g_streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto mock_ = CMock::GetMock(); + EXPECT_CALL(*mock_, fseek(testing::_, testing::_, testing::_)).WillOnce(testing::Return(-1)); + + WriteOptions opt; + opt.offset = 5; + string buf = "FsStreamWriteTest_0002"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), buf.length()), opt); + EXPECT_FALSE(retWr.IsSuccess()); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamMockTest-end FsStreamWriteTest_0002"; +} + +/** + * @tc.name: FsStreamReadTest_0001 + * @tc.desc: Test function of Read() interface for fail fseek. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamMockTest, FsStreamReadTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamMockTest-begin FsStreamReadTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(g_streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + void *buffer = std::malloc(4096); + ArrayBuffer arrayBuffer(buffer, 4096); + + auto mock_ = CMock::GetMock(); + EXPECT_CALL(*mock_, fseek(testing::_, testing::_, testing::_)).WillOnce(testing::Return(-1)); + + ReadOptions opt; + opt.offset = 5; + auto retRd = result->Read(arrayBuffer, opt); + EXPECT_FALSE(retRd.IsSuccess()); + + free(buffer); + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamMockTest-end FsStreamReadTest_0001"; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_stream/fs_stream_test.cpp b/interfaces/test/unittest/js/mod_fs/class_stream/fs_stream_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..770069c815e194194e186711fd3fe0d7355e56e5 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_stream/fs_stream_test.cpp @@ -0,0 +1,791 @@ +/* + * 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 "create_stream_core.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static const string streamFilePath = "/data/test/FsStreamCoreTest.txt"; + +class FsStreamTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + int32_t fd = open(streamFilePath.c_str(), CREATE | O_RDWR, 0644); + close(fd); + }; + static void TearDownTestCase() + { + rmdir(streamFilePath.c_str()); + }; + void SetUp() {}; + void TearDown() {}; +}; + +/** + * @tc.name: FsStreamCloseTest_0001 + * @tc.desc: Test function of Close() interface for close success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamCloseTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamCloseTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamCloseTest_0001"; +} + +/** + * @tc.name: FsStreamCloseTest_0002 + * @tc.desc: Test function of Close() interface for close fail. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamCloseTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamCloseTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + retCs = result->Close(); + EXPECT_FALSE(retCs.IsSuccess()); + auto err = retCs.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900005); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamCloseTest_0002"; +} + +/** + * @tc.name: FsStreamFlushTest_0001 + * @tc.desc: Test function of Flush() interface for null fp. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamFlushTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamFlushTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + auto retFl = result->Flush(); + EXPECT_FALSE(retFl.IsSuccess()); + auto err = retFl.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900005); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamFlushTest_0001"; +} + +/** + * @tc.name: FsStreamFlushTest_0002 + * @tc.desc: Test function of Flush() interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamFlushTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamFlushTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retFl = result->Flush(); + ASSERT_TRUE(retFl.IsSuccess()); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamFlushTest_0002"; +} + +/** + * @tc.name: FsStreamSeekTest_0001 + * @tc.desc: Test function of Seek() interface for null fp. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamSeekTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamSeekTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + auto retSk = result->Seek(0); + EXPECT_FALSE(retSk.IsSuccess()); + auto err = retSk.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900002); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamSeekTest_0001"; +} + +/** + * @tc.name: FsStreamSeekTest_0002 + * @tc.desc: Test function of Seek() interface for error whence < SEEK_SET (0). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamSeekTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamSeekTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + optional opt = -1; + auto retSk = result->Seek(0, opt); + EXPECT_FALSE(retSk.IsSuccess()); + auto err = retSk.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamSeekTest_0002"; +} + +/** + * @tc.name: FsStreamSeekTest_0003 + * @tc.desc: Test function of Seek() interface for error whence > SEEK_END (2). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamSeekTest_0003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamSeekTest_0003"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + optional opt = 3; + auto retSk = result->Seek(0, opt); + EXPECT_FALSE(retSk.IsSuccess()); + auto err = retSk.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamSeekTest_0003"; +} + +/** + * @tc.name: FsStreamSeekTest_0004 + * @tc.desc: Test function of Seek() interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamSeekTest_0004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamSeekTest_0004"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retSk = result->Seek(1); + ASSERT_TRUE(retSk.IsSuccess()); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamSeekTest_0004"; +} + +/** + * @tc.name: FsStreamWriteTest_0001 + * @tc.desc: Test function of Write() interface for string single argument fail null fp. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + auto retWr = result->Write("FsStreamWriteTest_0001"); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900005); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0001"; +} + +/** + * @tc.name: FsStreamWriteTest_0002 + * @tc.desc: Test function of Write() interface for ArrayBuffer single argument fail null fp. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + string buf = "FsStreamWriteTest_0001"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), 22)); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900005); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0002"; +} + +/** + * @tc.name: FsStreamWriteTest_0003 + * @tc.desc: Test function of Write() interface for string error offset. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0003"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.offset = -1; + + auto retWr = result->Write("FsStreamWriteTest_0003", opt); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0003"; +} + +/** + * @tc.name: FsStreamWriteTest_0004 + * @tc.desc: Test function of Write() interface for ArrayBuffer error offset. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0004"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.offset = -1; + + string buf = "FsStreamWriteTest_0004"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), 22), opt); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0004"; +} + +/** + * @tc.name: FsStreamWriteTest_0005 + * @tc.desc: Test function of Write() interface for string error encoding. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0005"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.encoding = "utf-16"; + + auto retWr = result->Write("FsStreamWriteTest_0005", opt); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0005"; +} + +/** + * @tc.name: FsStreamWriteTest_0006 + * @tc.desc: Test function of Write() interface for ArrayBuffer error encoding. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0006"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.encoding = "utf-16"; + + string buf = "FsStreamWriteTest_0006"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), 22), opt); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0004"; +} + +#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(__LP64__) +/** + * @tc.name: FsStreamWriteTest_0007 + * @tc.desc: Test function of Write() interface for string > UINT_MAX. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0007, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0007"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + size_t largeLength = static_cast(UINT_MAX) + 1; + string largeString(largeLength, 'a'); + + auto retWr = result->Write(largeString); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0005"; +} + +/** + * @tc.name: FsStreamWriteTest_0008 + * @tc.desc: Test function of Write() interface for ArrayBuffer > UINT_MAX. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0008, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0008"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + size_t largeLength = static_cast(UINT_MAX) + 1; + string largeString(largeLength, 'a'); + + auto retWr = result->Write(ArrayBuffer(static_cast(largeString.data()), largeLength)); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0008"; +} +#endif + +/** + * @tc.name: FsStreamWriteTest_0009 + * @tc.desc: Test function of Write() interface for string length < 0. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0009, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0009"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.length = -1; + + auto retWr = result->Write("FsStreamWriteTest_0009", opt); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0009"; +} + +/** + * @tc.name: FsStreamWriteTest_0010 + * @tc.desc: Test function of Write() interface for ArrayBuffer length < 0. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0010, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0010"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.length = -1; + + string buf = "FsStreamWriteTest_0010"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), 22), opt); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0010"; +} + +/** + * @tc.name: FsStreamWriteTest_0013 + * @tc.desc: Test function of Write() interface for string no permission. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0013, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0013"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retWr = result->Write("FsStreamWriteTest_0013"); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900005); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0013"; +} + +/** + * @tc.name: FsStreamWriteTest_0014 + * @tc.desc: Test function of Write() interface for ArrayBuffer no permission. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0014, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0014"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + string buf = "FsStreamWriteTest_0014"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), 22)); + EXPECT_FALSE(retWr.IsSuccess()); + EXPECT_EQ(retWr.GetError().GetErrNo(), 13900005); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0014"; +} + +/** + * @tc.name: FsStreamWriteTest_0015 + * @tc.desc: Test function of Write() interface for string success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0015, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0015"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.offset = 0; + opt.encoding = "utf-8"; + opt.length = 5; + + auto retWr = result->Write("FsStreamWriteTest_0015", opt); + ASSERT_TRUE(retWr.IsSuccess()); + + size_t retLen = retWr.GetData().value(); + EXPECT_EQ(retLen, 5); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0015"; +} + +/** + * @tc.name: FsStreamWriteTest_0016 + * @tc.desc: Test function of Write() interface for ArrayBuffer success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamWriteTest_0016, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamWriteTest_0016"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + WriteOptions opt; + opt.offset = 0; + opt.encoding = "utf-8"; + opt.length = 5; + + string buf = "FsStreamWriteTest_0016"; + auto retWr = result->Write(ArrayBuffer(static_cast(buf.data()), 22), opt); + ASSERT_TRUE(retWr.IsSuccess()); + + size_t retLen = retWr.GetData().value(); + EXPECT_EQ(retLen, 5); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamWriteTest_0016"; +} + +/** + * @tc.name: FsStreamReadTest_0001 + * @tc.desc: Test function of Read() interface for single argument null fp. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamReadTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamReadTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + void *buffer = std::malloc(4096); + ArrayBuffer arrayBuffer(buffer, 4096); + auto retRd = result->Read(arrayBuffer); + EXPECT_FALSE(retRd.IsSuccess()); + EXPECT_EQ(retRd.GetError().GetErrNo(), 13900005); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamReadTest_0001"; +} + +/** + * @tc.name: FsStreamReadTest_0002 + * @tc.desc: Test function of Read() interface for error offset. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamReadTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamReadTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + ReadOptions opt; + opt.offset = -1; + + void *buffer = std::malloc(4096); + ArrayBuffer arrayBuffer(buffer, 4096); + auto retRd = result->Read(arrayBuffer, opt); + EXPECT_FALSE(retRd.IsSuccess()); + EXPECT_EQ(retRd.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamReadTest_0002"; +} + +#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(__LP64__) +/** + * @tc.name: FsStreamReadTest_0003 + * @tc.desc: Test function of Read() interface for bufLen > UINT_MAX. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamReadTest_0003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamReadTest_0003"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + size_t largeLength = static_cast(UINT_MAX) + 1; + + void *buffer = std::malloc(largeLength); + ArrayBuffer arrayBuffer(buffer, largeLength); + auto retRd = result->Read(arrayBuffer); + EXPECT_FALSE(retRd.IsSuccess()); + EXPECT_EQ(retRd.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamReadTest_0003"; +} +#endif + +/** + * @tc.name: FsStreamReadTest_0004 + * @tc.desc: Test function of Read() interface for error length. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamReadTest_0004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamReadTest_0004"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + ReadOptions opt; + opt.length = -1; + + void *buffer = std::malloc(4096); + ArrayBuffer arrayBuffer(buffer, 4096); + auto retRd = result->Read(arrayBuffer, opt); + EXPECT_FALSE(retRd.IsSuccess()); + EXPECT_EQ(retRd.GetError().GetErrNo(), 13900020); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamReadTest_0004"; +} + +/** + * @tc.name: FsStreamReadTest_0005 + * @tc.desc: Test function of Read() interface for no permission. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamReadTest_0005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamReadTest_0005"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "w"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + void *buffer = std::malloc(4096); + ArrayBuffer arrayBuffer(buffer, 4096); + auto retRd = result->Read(arrayBuffer); + EXPECT_FALSE(retRd.IsSuccess()); + EXPECT_EQ(retRd.GetError().GetErrNo(), 13900005); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamReadTest_0005"; +} + +/** + * @tc.name: FsStreamReadTest_0006 + * @tc.desc: Test function of Read() interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsStreamTest, FsStreamReadTest_0006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsStreamTest-begin FsStreamReadTest_0006"; + auto ret = CreateStreamCore::DoCreateStream(streamFilePath, "r+"); + ASSERT_TRUE(ret.IsSuccess()); + auto result = ret.GetData().value(); + + ReadOptions opt; + opt.offset = 0; + opt.length = 5; + void *buffer = std::malloc(4096); + ArrayBuffer arrayBuffer(buffer, 4096); + + auto retRd = result->Read(arrayBuffer, opt); + ASSERT_TRUE(retRd.IsSuccess()); + + size_t retLen = retRd.GetData().value(); + EXPECT_EQ(retLen, 0); + + auto retCs = result->Close(); + ASSERT_TRUE(retCs.IsSuccess()); + + GTEST_LOG_(INFO) << "FsStreamTest-end FsStreamReadTest_0006"; +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_stream/mock/c_mock.cpp b/interfaces/test/unittest/js/mod_fs/class_stream/mock/c_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa513e4fee61fc2fa2354385d08279b0e69def0e --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_stream/mock/c_mock.cpp @@ -0,0 +1,97 @@ +/* + * 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 "c_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { + +thread_local std::shared_ptr CMock::cMock = nullptr; +thread_local bool CMock::mockable = false; + +std::shared_ptr CMock::GetMock() +{ + if (cMock == nullptr) { + cMock = std::make_shared(); + } + return cMock; +} + +void CMock::EnableMock() +{ + mockable = true; +} + +void CMock::DisableMock() +{ + cMock = nullptr; + mockable = false; +} + +bool CMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +#ifdef __cplusplus +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int fseek(FILE *stream, long len, int offset) +{ + if (CMock::IsMockable()) { + return CMock::GetMock()->fseek(stream, len, offset); + } + + static int (*realFseek)(FILE *, long, int) = []() { + auto func = (int (*)(FILE *, long, int))dlsym(RTLD_NEXT, "fseek"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real fseek: " << dlerror(); + } + return func; + }(); + + if (!realFseek) { + return -1; + } + + return realFseek(stream, len, offset); +} + +long ftell(FILE *stream) +{ + if (CMock::IsMockable()) { + return CMock::GetMock()->ftell(stream); + } + + static long (*realFtell)(FILE *) = []() { + auto func = (long (*)(FILE *))dlsym(RTLD_NEXT, "ftell"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ftell: " << dlerror(); + } + return func; + }(); + + if (!realFtell) { + return -1; + } + + return realFtell(stream); +} +} // extern "C" +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_stream/mock/c_mock.h b/interfaces/test/unittest/js/mod_fs/class_stream/mock/c_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..9baf3240cc265ff73f474a16c5002778b333e4e8 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_stream/mock/c_mock.h @@ -0,0 +1,49 @@ +/* + * 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_CLASS_STREAM_MOCK_C_MOCK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_CLASS_STREAM_MOCK_C_MOCK_H + +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { + +class ICMock { +public: + virtual ~ICMock() = default; + virtual int fseek(FILE *, long, int) = 0; + virtual long ftell(FILE *) = 0; +}; + +class CMock : public ICMock { +public: + MOCK_METHOD(int, fseek, (FILE *, long, int), (override)); + MOCK_METHOD(long, ftell, (FILE *), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr cMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_CLASS_STREAM_MOCK_C_MOCK_H \ 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 0000000000000000000000000000000000000000..fe585ef7104b6cea9541622392a5c523b052b3e3 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_file_watcher_mock_test.cpp @@ -0,0 +1,1324 @@ +/* + * 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"; + EventfdMock::EnableMock(); + InotifyMock::EnableMock(); + PollMock::EnableMock(); + UnistdMock::EnableMock(); +} + +void FsFileWatcherMockTest::TearDownTestCase(void) +{ + EventfdMock::DisableMock(); + InotifyMock::DisableMock(); + PollMock::DisableMock(); + UnistdMock::DisableMock(); + 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"; +} + +inline const int32_t EXPECTED_WD = 100; +inline const int32_t UNEXPECTED_WD = 200; + +/** + * @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 = "fakePath/FsFileWatcherMockTest_StartNotify_001"; + info->events = IN_CREATE | IN_DELETE; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(EXPECTED_WD)); + // Do testing + int32_t result = watcher.StartNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + EXPECT_EQ(info->wd, EXPECTED_WD); + 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StartNotify_002"; + info->events = IN_CREATE | IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + 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, EXPECTED_WD); +} + +/** + * @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; + // Build test parameters + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/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; + // Build test parameters + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/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_StartNotify_006 + * @tc.desc: Test function of FsFileWatcher::StartNotify interface for SUCCESS when path is already watched. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_StartNotify_006, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_StartNotify_006"; + // Prepare test parameters + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StartNotify_006"; + info->events = IN_CREATE; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + auto cachedInfo = std::make_shared(nullptr); + cachedInfo->fileName = "fakePath/FsFileWatcherMockTest_StartNotify_006"; + cachedInfo->events = IN_DELETE; + cachedInfo->wd = EXPECTED_WD; + watcher.dataCache_.AddWatcherInfo(cachedInfo); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_add_watch(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::Return(EXPECTED_WD)); + // Do testing + int32_t result = watcher.StartNotify(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_EQ(result, ERRNO_NOERR); + EXPECT_EQ(info->wd, EXPECTED_WD); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_StartNotify_006"; +} + +/** + * @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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_001"; + info->events = IN_CREATE | IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 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(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; + // Prepare test parameters + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_003"; + info->events = IN_CREATE; + info->wd = EXPECTED_WD; + // 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_004"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_005"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_006"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_006"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = EXPECTED_WD; + 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_007"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_007"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = EXPECTED_WD; + 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(EXPECTED_WD)); + // 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_008"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_008"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = EXPECTED_WD; + 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_009"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + watcher.dataCache_.AddWatcherInfo(info); + // Set having remainingEvents condition + auto remainingInfo = std::make_shared(nullptr); + remainingInfo->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_009"; + remainingInfo->events = IN_CREATE; + remainingInfo->wd = EXPECTED_WD; + 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(UNEXPECTED_WD)); + // 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 + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_StopNotify_010"; + info->events = IN_DELETE; + info->wd = EXPECTED_WD; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.notifyFd_ = 1; + 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 + uint32_t mask = IN_CREATE; + struct inotify_event event = { .wd = EXPECTED_WD, .mask = mask, .cookie = 0, .len = 0 }; + // Prepare test condition + auto callback = std::make_shared(); + auto info = std::make_shared(callback); + info->fileName = "fakePath/FsFileWatcherMockTest_NotifyEvent_001"; + info->events = mask; + info->wd = EXPECTED_WD; + 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 + 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 = EXPECTED_WD; + 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 = "fakePath/FsFileWatcherMockTest_NotifyEvent_002"; + info->events = mask; + info->wd = EXPECTED_WD; + 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 + struct inotify_event event = { .wd = EXPECTED_WD, .mask = IN_CREATE, .cookie = 0, .len = 0 }; + // Prepare test condition + auto callback = std::make_shared(); + auto info = std::make_shared(callback); + info->fileName = "fakePath/FsFileWatcherMockTest_NotifyEvent_004"; + info->events = IN_MODIFY; // Not matched mask + info->wd = UNEXPECTED_WD; // 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"; +} + +/** + * @tc.name: FsFileWatcherMockTest_AddWatcherInfo_001 + * @tc.desc: Test function of FsFileWatcher::AddWatcherInfo interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_AddWatcherInfo_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_AddWatcherInfo_001"; + // Prepare test parameters + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_AddWatcherInfo_001"; + info->events = IN_CREATE; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + auto cachedInfo0 = std::make_shared(nullptr); + cachedInfo0->fileName = "fakePath/FsFileWatcherMockTest_AddWatcherInfo_001_cachedInfo0"; + watcher.dataCache_.AddWatcherInfo(cachedInfo0); + + auto cachedInfo1 = std::make_shared(nullptr); + cachedInfo1->fileName = "fakePath/FsFileWatcherMockTest_AddWatcherInfo_001"; + cachedInfo1->events = IN_DELETE; + watcher.dataCache_.AddWatcherInfo(cachedInfo1); + + auto callback = std::make_shared(); + auto cachedInfo2 = std::make_shared(callback); + cachedInfo2->fileName = "fakePath/FsFileWatcherMockTest_AddWatcherInfo_001"; + cachedInfo2->events = IN_CREATE; + watcher.dataCache_.AddWatcherInfo(cachedInfo2); + + // Set mock behaviors + EXPECT_CALL(*callback, IsStrictEquals(testing::_)).Times(1).WillOnce(testing::Return(false)); + // Do testing + bool result = watcher.AddWatcherInfo(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(callback.get()); + EXPECT_TRUE(result); + cachedInfo2->callback = nullptr; + watcher.dataCache_.ClearCache(); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_AddWatcherInfo_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_AddWatcherInfo_002 + * @tc.desc: Test function of FsFileWatcher::AddWatcherInfo interface for FAILURE when param is nullptr. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_AddWatcherInfo_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_AddWatcherInfo_002"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Do testing + bool result = watcher.AddWatcherInfo(nullptr); + // Verify results + EXPECT_FALSE(result); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_AddWatcherInfo_002"; +} + +/** + * @tc.name: FsFileWatcherMockTest_AddWatcherInfo_003 + * @tc.desc: Test function of FsFileWatcher::AddWatcherInfo interface for FAILURE when having same info. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_AddWatcherInfo_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_AddWatcherInfo_003"; + // Prepare test parameters + auto info = std::make_shared(nullptr); + info->fileName = "fakePath/FsFileWatcherMockTest_AddWatcherInfo_003"; + info->events = IN_CREATE; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + auto callback = std::make_shared(); + auto cachedInfo = std::make_shared(callback); + cachedInfo->fileName = "fakePath/FsFileWatcherMockTest_AddWatcherInfo_003"; + cachedInfo->events = IN_CREATE; + watcher.dataCache_.AddWatcherInfo(cachedInfo); + // Set mock behaviors + EXPECT_CALL(*callback, IsStrictEquals(testing::_)).Times(1).WillOnce(testing::Return(true)); + // Do testing + bool result = watcher.AddWatcherInfo(info); + // Verify results + testing::Mock::VerifyAndClearExpectations(callback.get()); + EXPECT_FALSE(result); + cachedInfo->callback = nullptr; + watcher.dataCache_.ClearCache(); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_AddWatcherInfo_003"; +} + +/** + * @tc.name: FsFileWatcherMockTest_RemoveWatcherInfo_001 + * @tc.desc: Test function of FsFileWatcher::RemoveWatcherInfo interface for FAILURE when param is nullptr. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_RemoveWatcherInfo_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_RemoveWatcherInfo_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + // Do testing + auto result = watcher.RemoveWatcherInfo(nullptr); + // Verify results + EXPECT_EQ(result, EINVAL); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_RemoveWatcherInfo_001"; +} + +/** + * @tc.name: FsFileWatcherMockTest_DestroyTaskThead_001 + * @tc.desc: Test function of FsFileWatcher::DestroyTaskThead interface when taskRunning is true. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsFileWatcherMockTest, FsFileWatcherMockTest_DestroyTaskThead_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-begin FsFileWatcherMockTest_DestroyTaskThead_001"; + // Prepare test condition + FsFileWatcher &watcher = FsFileWatcher::GetInstance(); + watcher.taskRunning_ = true; + // Do testing + watcher.DestroyTaskThead(); + // Verify results + EXPECT_FALSE(watcher.taskRunning_); + GTEST_LOG_(INFO) << "FsFileWatcherMockTest-end FsFileWatcherMockTest_DestroyTaskThead_001"; +} + +} // 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 0000000000000000000000000000000000000000..805c6af56f3a2981aa7320def7b70a810c303796 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/fs_watcher_mock_test.cpp @@ -0,0 +1,266 @@ +/* + * 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"; + InotifyMock::EnableMock(); + UnistdMock::EnableMock(); +} + +void FsWatcherMockTest::TearDownTestCase(void) +{ + InotifyMock::DisableMock(); + UnistdMock::DisableMock(); + 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/common/fs_err_code.h b/interfaces/test/unittest/js/mod_fs/common/fs_err_code.h new file mode 100644 index 0000000000000000000000000000000000000000..7e8a4cbbdc2423d73cdad3d0b6a8d0063fb7c6c9 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/common/fs_err_code.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef 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 { + +enum FsErrCode { + E_IO_CODE = 13900005, + E_INVAL_CODE = 13900020, +}; + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#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 0000000000000000000000000000000000000000..1b140d0428cc49353db52aed5122a6161466794b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.cpp @@ -0,0 +1,83 @@ +/* + * 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" + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr EventfdMock::eventfdMock = nullptr; +thread_local bool EventfdMock::mockable = false; + +std::shared_ptr EventfdMock::GetMock() +{ + if (eventfdMock == nullptr) { + eventfdMock = std::make_shared(); + } + return eventfdMock; +} + +void EventfdMock::EnableMock() +{ + mockable = true; +} + +void EventfdMock::DisableMock() +{ + eventfdMock = nullptr; + mockable = false; +} + +bool EventfdMock::IsMockable() +{ + return mockable; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#ifdef __cplusplus +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int eventfd(unsigned int count, int flags) +{ + if (EventfdMock::IsMockable()) { + return EventfdMock::GetMock()->eventfd(count, flags); + } + + static int (*realEventfd)(unsigned int, int) = []() { + auto func = (int (*)(unsigned int, int))dlsym(RTLD_NEXT, "eventfd"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real eventfd: " << dlerror(); + } + return func; + }(); + + if (!realEventfd) { + return -1; + } + + return realEventfd(count, flags); +} + +} // extern "C" +#endif \ 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 0000000000000000000000000000000000000000..97dd8430f20279c9d2be5bf348bd4a42a303624b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/eventfd_mock.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef 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 EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr eventfdMock; + static thread_local bool mockable; +}; + +} // 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 0000000000000000000000000000000000000000..729d21a557cce5c93de44593eff6f29a10ff36ee --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.cpp @@ -0,0 +1,125 @@ +/* + * 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" + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr InotifyMock::inotifyMock = nullptr; +thread_local bool InotifyMock::mockable = false; + +std::shared_ptr InotifyMock::GetMock() +{ + if (inotifyMock == nullptr) { + inotifyMock = std::make_shared(); + } + return inotifyMock; +} + +void InotifyMock::EnableMock() +{ + mockable = true; +} + +void InotifyMock::DisableMock() +{ + inotifyMock = nullptr; + mockable = false; +} + +bool InotifyMock::IsMockable() +{ + return mockable; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#ifdef __cplusplus +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int inotify_init() +{ + if (InotifyMock::IsMockable()) { + return InotifyMock::GetMock()->inotify_init(); + } + + static int (*realInotifyInit)() = []() { + auto func = (int (*)())dlsym(RTLD_NEXT, "inotify_init"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real inotify_init: " << dlerror(); + } + return func; + }(); + + if (!realInotifyInit) { + return -1; + } + + return realInotifyInit(); +} + +int inotify_add_watch(int fd, const char *pathname, uint32_t mask) +{ + if (InotifyMock::IsMockable()) { + return InotifyMock::GetMock()->inotify_add_watch(fd, pathname, mask); + } + + static int (*realInotifyAddWatch)(int, const char *, uint32_t) = []() { + auto func = (int (*)(int, const char *, uint32_t))dlsym(RTLD_NEXT, "inotify_add_watch"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real inotify_add_watch: " << dlerror(); + } + return func; + }(); + + if (!realInotifyAddWatch) { + return -1; + } + + return realInotifyAddWatch(fd, pathname, mask); +} + +int inotify_rm_watch(int fd, int wd) +{ + if (InotifyMock::IsMockable()) { + return InotifyMock::GetMock()->inotify_rm_watch(fd, wd); + } + + static int (*realInotifyRmWatch)(int, int) = []() { + auto func = (int (*)(int, int))dlsym(RTLD_NEXT, "inotify_rm_watch"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real inotify_rm_watch: " << dlerror(); + } + return func; + }(); + + if (!realInotifyRmWatch) { + return -1; + } + + return realInotifyRmWatch(fd, wd); +} + +} // extern "C" +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.h b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..233403309185aff66129b983a3214bfc01aab51e --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/inotify_mock.h @@ -0,0 +1,57 @@ +/* + * 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_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)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr inotifyMock; + static thread_local bool mockable; +}; + +} // 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/mock/mock_progress_listener.h b/interfaces/test/unittest/js/mod_fs/mock/mock_progress_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..e7851c98d42e75ec5926688da213d9884c650507 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/mock_progress_listener.h @@ -0,0 +1,29 @@ +/* + * 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_PROGRESS_LISTENER_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_MOCK_PROGRESS_LISTENER_H + +#include +#include "i_progress_listener.h" + +namespace OHOS::FileManagement::ModuleFileIO { +class MockProgressListener : public IProgressListener { +public: + MOCK_METHOD(void, InvokeListener, (uint64_t progressSize, uint64_t totalSize), (const, override)); +}; +} // namespace OHOS::FileManagement::ModuleFileIO + +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_MOCK_MOCK_PROGRESS_LISTENER_H 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 0000000000000000000000000000000000000000..c1004d84f5ee144130ba40352c7c7a4d4e747ede --- /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 0000000000000000000000000000000000000000..6e2095ab2c7d7d8bc21fc5aee2baa0080dcbcff2 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/poll_mock.cpp @@ -0,0 +1,83 @@ +/* + * 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" + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr PollMock::pollMock = nullptr; +thread_local bool PollMock::mockable = false; + +std::shared_ptr PollMock::GetMock() +{ + if (pollMock == nullptr) { + pollMock = std::make_shared(); + } + return pollMock; +} + +void PollMock::EnableMock() +{ + mockable = true; +} + +void PollMock::DisableMock() +{ + pollMock = nullptr; + mockable = false; +} + +bool PollMock::IsMockable() +{ + return mockable; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#ifdef __cplusplus +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int poll(struct pollfd *fds, nfds_t n, int timeout) +{ + if (PollMock::IsMockable()) { + return PollMock::GetMock()->poll(fds, n, timeout); + } + + static int (*realPoll)(struct pollfd * fds, nfds_t n, int timeout) = []() { + auto func = (int (*)(struct pollfd *, nfds_t, int))dlsym(RTLD_NEXT, "poll"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real poll: " << dlerror(); + } + return func; + }(); + + if (!realPoll) { + return -1; + } + + return realPoll(fds, n, timeout); +} + +} // extern "C" +#endif \ 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 0000000000000000000000000000000000000000..da771e4ec299c09fdc857484fdfa4448a5b1cbd7 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/poll_mock.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef 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 EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr pollMock; + static thread_local bool mockable; +}; + +} // 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 0000000000000000000000000000000000000000..cda59d9bf97f0d8affb7ba526db72d725302820b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.cpp @@ -0,0 +1,125 @@ +/* + * 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" + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace Test { + +thread_local std::shared_ptr UnistdMock::unistdMock = nullptr; +thread_local bool UnistdMock::mockable = false; + +std::shared_ptr UnistdMock::GetMock() +{ + if (unistdMock == nullptr) { + unistdMock = std::make_shared(); + } + return unistdMock; +} + +void UnistdMock::EnableMock() +{ + mockable = true; +} + +void UnistdMock::DisableMock() +{ + unistdMock = nullptr; + mockable = false; +} + +bool UnistdMock::IsMockable() +{ + return mockable; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#ifdef __cplusplus +extern "C" { +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int access(const char *filename, int amode) +{ + if (UnistdMock::IsMockable()) { + return UnistdMock::GetMock()->access(filename, amode); + } + + static int (*realAccess)(const char *filename, int amode) = []() { + auto func = (int (*)(const char *, int))dlsym(RTLD_NEXT, "access"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real access: " << dlerror(); + } + return func; + }(); + + if (!realAccess) { + return -1; + } + + return realAccess(filename, amode); +} + +int close(int fd) +{ + if (UnistdMock::IsMockable()) { + return UnistdMock::GetMock()->close(fd); + } + + static int (*realClose)(int fd) = []() { + auto func = (int (*)(int))dlsym(RTLD_NEXT, "close"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real close: " << dlerror(); + } + return func; + }(); + + if (!realClose) { + return -1; + } + + return realClose(fd); +} + +ssize_t read(int fd, void *buf, size_t count) +{ + if (UnistdMock::IsMockable()) { + return UnistdMock::GetMock()->read(fd, buf, count); + } + + static ssize_t (*realRead)(int fd, void *buf, size_t count) = []() { + auto func = (ssize_t(*)(int, void *, size_t))dlsym(RTLD_NEXT, "read"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real read: " << dlerror(); + } + return func; + }(); + + if (!realRead) { + return 0; + } + + return realRead(fd, buf, count); +} + +} // extern "C" +#endif \ 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 0000000000000000000000000000000000000000..ec6f961e197fa126e3fb1776135af16bbc0add62 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/mock/unistd_mock.h @@ -0,0 +1,57 @@ +/* + * 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 EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr unistdMock; + static thread_local bool mockable; +}; + +} // 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/access_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/access_core_mock_test.cpp index 4d9355d9cdbb3caf5449287cfca6496bf34982c3..a95e4eea40ce89e47f14135cc298a08d347ecfa0 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/access_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/access_core_mock_test.cpp @@ -67,7 +67,7 @@ void AccessCoreMockTest::TearDown(void) */ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "NClassTest-begin AccessCoreMockTest_DoAccess_001"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-begin AccessCoreMockTest_DoAccess_001"; std::string path = "TEST"; std::optional mode; @@ -76,7 +76,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_001, testing::ext::Test auto res = AccessCore::DoAccess(path, mode); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "NClassTest-end AccessCoreMockTest_DoAccess_001"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-end AccessCoreMockTest_DoAccess_001"; } /** @@ -88,7 +88,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_001, testing::ext::Test */ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_002, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "NClassTest-begin AccessCoreMockTest_DoAccess_002"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-begin AccessCoreMockTest_DoAccess_002"; std::string path = "TEST"; std::optional mode; @@ -98,7 +98,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_002, testing::ext::Test auto res = AccessCore::DoAccess(path, mode); EXPECT_EQ(res.IsSuccess(), true); - GTEST_LOG_(INFO) << "NClassTest-end AccessCoreMockTest_DoAccess_002"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-end AccessCoreMockTest_DoAccess_002"; } /** @@ -110,7 +110,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_002, testing::ext::Test */ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_003, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "NClassTest-begin AccessCoreMockTest_DoAccess_003"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-begin AccessCoreMockTest_DoAccess_003"; std::string path = "TEST"; AccessModeType mode = AccessModeType::EXIST; @@ -120,7 +120,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_003, testing::ext::Test auto res = AccessCore::DoAccess(path, mode, flag); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "NClassTest-end AccessCoreMockTest_DoAccess_003"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-end AccessCoreMockTest_DoAccess_003"; } /** @@ -132,7 +132,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_003, testing::ext::Test */ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_004, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "NClassTest-begin AccessCoreMockTest_DoAccess_004"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-begin AccessCoreMockTest_DoAccess_004"; std::string path = "TEST"; AccessModeType mode = AccessModeType::EXIST; @@ -143,30 +143,7 @@ HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_004, testing::ext::Test auto res = AccessCore::DoAccess(path, mode, flag); EXPECT_EQ(res.IsSuccess(), true); - GTEST_LOG_(INFO) << "NClassTest-end AccessCoreMockTest_DoAccess_004"; -} - -/** - * @tc.name: AccessCoreMockTest_DoAccess_005 - * @tc.desc: Test function of AccessCore::DoAccess interface for success. - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 1 - */ -HWTEST_F(AccessCoreMockTest, AccessCoreMockTest_DoAccess_005, testing::ext::TestSize.Level1) -{ - GTEST_LOG_(INFO) << "AccessCoreMockTest-begin AccessCoreMockTest_DoAccess_005"; - - std::string path = DISTRIBUTED_FILE_PREFIX; - AccessModeType mode = AccessModeType::EXIST; - AccessFlag flag = LOCAL_FLAG; - - EXPECT_CALL(*uvMock, uv_fs_access(_, _, _, _, _)).WillOnce(Return(0)); - - auto res = AccessCore::DoAccess(path, mode, flag); - EXPECT_EQ(res.IsSuccess(), true); - - GTEST_LOG_(INFO) << "AccessCoreMockTest-end AccessCoreMockTest_DoAccess_005"; + GTEST_LOG_(INFO) << "AccessCoreMockTest-end AccessCoreMockTest_DoAccess_004"; } } // OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/access_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/access_core_test.cpp index b7966bd3cb40a3ef28a87366b7d209e395d31290..6460d9a657d69bc56bb344028401b8c1b68c5904 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/access_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/access_core_test.cpp @@ -24,7 +24,6 @@ namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; using namespace testing::ext; using namespace std; - const mode_t DIR_PERMISSIONS = 0755; class AccessCoreTest : public testing::Test { @@ -61,8 +60,7 @@ void AccessCoreTest::TearDown(void) } // 递归创建多级目录的辅助函数 -bool CreateDirectoryRecursive(const std::string& path) -{ +bool CreateDirectoryRecursive(const std::string& path) { if (path.empty()) { return false; } @@ -74,8 +72,7 @@ bool CreateDirectoryRecursive(const std::string& path) pos++; } - while ((pos = path.find('/', pos)) != std::string::npos) - { + while ((pos = path.find('/', pos)) != std::string::npos) { dir = path.substr(0, pos++); if (dir.empty()) { continue; @@ -87,8 +84,7 @@ bool CreateDirectoryRecursive(const std::string& path) } } - if (mkdir(path.c_str(), DIR_PERMISSIONS) == -1 && errno != EEXIST) - { + if (mkdir(path.c_str(), DIR_PERMISSIONS) == -1 && errno != EEXIST) { return false; } return true; @@ -212,7 +208,7 @@ HWTEST_F(AccessCoreTest, AccessCoreTest_DoAccess_006, testing::ext::TestSize.Lev { GTEST_LOG_(INFO) << "AccessCoreTest-begin AccessCoreTest_DoAccess_006"; - std::string path = "test"; + std::string path = "AccessCoreTest"; AccessModeType mode = AccessModeType::EXIST; AccessFlag flag = LOCAL_FLAG; 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 0000000000000000000000000000000000000000..6e832264aaceae17bf33a0678fd5dbe2c7647f43 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_mock_test.cpp @@ -0,0 +1,548 @@ +/* + * 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_progress_listener.h" +#include "mock/uv_fs_mock.h" +#include "poll_mock.h" +#include "unistd_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; + +private: + static constexpr mode_t permission0755 = 0755; + static constexpr mode_t permission0644 = 0644; +}; + +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(), 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); + } + close(fd); + uvMock = std::make_shared(); + Uvfs::ins = uvMock; + InotifyMock::EnableMock(); + PollMock::EnableMock(); + UnistdMock::EnableMock(); +} + +void CopyCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + int ret = remove(srcFile.c_str()); + EXPECT_TRUE(ret == 0); + rmdir(srcDir.c_str()); + rmdir(destDir.c_str()); + rmdir(testDir.c_str()); + Uvfs::ins = nullptr; + uvMock = nullptr; + InotifyMock::DisableMock(); + PollMock::DisableMock(); + UnistdMock::DisableMock(); +} + +void CopyCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void CopyCoreMockTest::TearDown(void) +{ + CopyCore::callbackMap_.clear(); + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: CopyCoreMockTest_CopyFile_001 + * @tc.desc: Test function of CopyCore::CopyFile interface for 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; + 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); + 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; + 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"; +} + +/** + * @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(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + EXPECT_TRUE(false); + } + close(fd); + + auto inotifyMock = InotifyMock::GetMock(); + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + infos->notifyFd = 1; + 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); + EXPECT_EQ(res, UNKNOWN_ERR); + + 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"; +} + +/** + * @tc.name: CopyCoreMockTest_CopySubDir_002 + * @tc.desc: Test CopyCore::CopySubDir when iter == CopyCore::callbackMap_.end() + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_CopySubDir_002"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + EXPECT_TRUE(false); + } + close(fd); + + auto inotifyMock = InotifyMock::GetMock(); + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + infos->notifyFd = 1; + auto unistdMock = UnistdMock::GetMock(); + CopyCore::callbackMap_.clear(); + + 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); + EXPECT_EQ(res, UNKNOWN_ERR); + + 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_002"; +} + +/** + * @tc.name: CopyCoreMockTest_CopySubDir_003 + * @tc.desc: Test CopyCore::CopySubDir when iter->second == nullptr + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CopySubDir_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_CopySubDir_003"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + GTEST_LOG_(INFO) << "Open test file failed! ret: " << fd << ", errno: " << errno; + EXPECT_TRUE(false); + } + close(fd); + + auto inotifyMock = InotifyMock::GetMock(); + string destSubDir = destDir + "/sub_dir"; + auto infos = make_shared(); + infos->notifyFd = 1; + auto unistdMock = UnistdMock::GetMock(); + CopyCore::callbackMap_[*infos] = nullptr; + + 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); + EXPECT_EQ(res, UNKNOWN_ERR); + + int ret = remove(subFile.c_str()); + EXPECT_TRUE(ret == 0); + rmdir(subDir.c_str()); + rmdir(destSubDir.c_str()); + CopyCore::callbackMap_.clear(); + + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_CopySubDir_003"; +} + +/** + * @tc.name: CopyCoreMockTest_ReceiveComplete_001 + * @tc.desc: Test CopyCore::ReceiveComplete in normal case + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReceiveComplete_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReceiveComplete_001"; + + auto mockListener = std::make_shared(); + auto callback = std::make_shared(mockListener); + callback->maxProgressSize = 50; + auto entry = std::make_shared(callback); + entry->progressSize = 100; + entry->totalSize = 200; + + EXPECT_CALL(*mockListener, InvokeListener(entry->progressSize, entry->totalSize)).Times(1); + CopyCore::ReceiveComplete(entry); + + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReceiveComplete_001"; +} + +/** + * @tc.name: CopyCoreMockTest_ReceiveComplete_002 + * @tc.desc: Test CopyCore::ReceiveComplete when processedSize < entry->callback->maxProgressSize + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReceiveComplete_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReceiveComplete_002"; + + auto mockListener = std::make_shared(); + auto callback = std::make_shared(mockListener); + callback->maxProgressSize = 100; + auto entry = std::make_shared(callback); + entry->progressSize = 50; // Mock valid progressSize + entry->totalSize = 200; // Mock valid totalSize, and progressSize < totalSize + + EXPECT_CALL(*mockListener, InvokeListener(testing::_, testing::_)).Times(0); + CopyCore::ReceiveComplete(entry); + + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReceiveComplete_002"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_001 + * @tc.desc: Test function of CopyCoreMockTest::ReadNotifyEvent interface for SUCCESS when read valid event data. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_001"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + 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 + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_001"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_002 + * @tc.desc: Test function of CopyCore::ReadNotifyEvent interface for FAILURE when read returns -1. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_002"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, -1)); + // Do testing + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_EQ(errno, EIO); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_002"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEvent_003 + * @tc.desc: Test function of CopyCore::ReadNotifyEvent interface for SUCCESS when read returns 0 (EOF). + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEvent_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEvent_003"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + auto callback = CopyCore::RegisterListener(infos); + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(0, 0)); + // Do testing + CopyCore::ReadNotifyEvent(infos); + // Verify results + EXPECT_NE(callback, nullptr); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_EQ(errno, 0); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEvent_003"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEventLocked_001 + * @tc.desc: Test ReadNotifyEventLocked when closed is false. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEventLocked_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEventLocked_001"; + // Prepare test condition + auto infos = make_shared(); + auto callback = std::make_shared(nullptr); + callback->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 + CopyCore::ReadNotifyEventLocked(infos, callback); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_FALSE(callback->reading); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEventLocked_001"; +} + +/** + * @tc.name: CopyCoreMockTest_ReadNotifyEventLocked_002 + * @tc.desc: Test ReadNotifyEventLocked when close after read. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_ReadNotifyEventLocked_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_ReadNotifyEventLocked_002"; + // Prepare test condition + auto infos = make_shared(); + auto callback = std::make_shared(nullptr); + callback->closed = false; + // Set mock behaviors + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([callback](int fd, void *buf, size_t count) { + errno = EIO; + callback->closed = true; + return 0; + }); + EXPECT_CALL(*unistdMock, close(testing::_)).WillRepeatedly(testing::Return(0)); + // Do testing + CopyCore::ReadNotifyEventLocked(infos, callback); + // Verify results + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_FALSE(callback->closed); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_ReadNotifyEventLocked_002"; +} + +/** + * @tc.name: CopyCoreMockTest_GetNotifyId_001 + * @tc.desc: Test function of CopyCore::GetNotifyId interface for SUCCESS. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_GetNotifyId_001, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_GetNotifyId_001"; + // Prepare test condition + auto infos = make_shared(); + infos->run = true; + infos->exceptionCode = ERRNO_NOERR; + infos->eventFd = 1; + infos->notifyFd = 1; + + auto callback = CopyCore::RegisterListener(infos); + // Set mock behaviors + auto pollMock = PollMock::GetMock(); + EXPECT_CALL(*pollMock, poll(testing::_, testing::_, testing::_)) + .Times(1) + .WillOnce([infos](struct pollfd *fds, nfds_t n, int timeout) { + fds[1].revents = POLLIN; + infos->run = false; // Ensure the loop will exit + return 1; + }); + // Do testing + CopyCore::GetNotifyEvent(infos); + // Verify results + testing::Mock::VerifyAndClearExpectations(pollMock.get()); + EXPECT_NE(callback, nullptr); + EXPECT_FALSE(infos->run); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_GetNotifyId_001"; +} + +/** + * @tc.name: CopyCoreMockTest_GetNotifyId_002 + * @tc.desc: Test function of CopyCore::GetNotifyId interface fails when callback is nullptr. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 0 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_GetNotifyId_002, testing::ext::TestSize.Level0) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_GetNotifyId_002"; + // Prepare test condition + auto infos = make_shared(); + // Do testing + CopyCore::GetNotifyEvent(infos); + // Verify results + EXPECT_EQ(infos->exceptionCode, EINVAL); + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_GetNotifyId_002"; +} + +/** + * @tc.name: CopyCoreMockTest_CreateFileInfos_001 + * @tc.desc: Test function of CopyCore::CreateFileInfos interface with listener and copySignal. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreMockTest, CopyCoreMockTest_CreateFileInfos_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreMockTest-begin CopyCoreMockTest_CreateFileInfos_001"; + + auto copySignal = std::make_shared(); + copySignal->taskSignal_ = std::make_shared(); + auto options = std::make_optional(); + options->progressListener = std::make_shared(); + options->copySignal = std::move(copySignal); + + auto [errCode, infos] = CopyCore::CreateFileInfos(srcFile, destFile, options); + EXPECT_EQ(errCode, ERRNO_NOERR); + EXPECT_NE(infos, nullptr); + if (infos) { + EXPECT_TRUE(infos->hasListener); + EXPECT_NE(infos->listener, nullptr); + EXPECT_NE(infos->taskSignal, nullptr); + } + + GTEST_LOG_(INFO) << "CopyCoreMockTest-end CopyCoreMockTest_CreateFileInfos_001"; +} + +} // 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 new file mode 100644 index 0000000000000000000000000000000000000000..6c9da75aceba83a4d4cc660fb418cfaf03ae08c3 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_core_test.cpp @@ -0,0 +1,1145 @@ +/* + * 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 +#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(); + + static const string testDir; + static const string srcDir; + static const string destDir; + static const string srcFile; + static const string destFile; + +private: + static constexpr mode_t permission0755 = 0755; // rwxr-xr-x + static constexpr mode_t permission0644 = 0644; // rw-r--r-- +}; + +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"; + 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); + } + close(fd); +} + +void CopyCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + int ret = remove(srcFile.c_str()); + EXPECT_TRUE(ret == 0); + rmdir(srcDir.c_str()); + rmdir(destDir.c_str()); + rmdir(testDir.c_str()); +} + +void CopyCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void CopyCoreTest::TearDown(void) +{ + CopyCore::callbackMap_.clear(); + GTEST_LOG_(INFO) << "TearDown"; +} + +inline const int32_t EXPECTED_WD = 100; +inline const int32_t UNEXPECTED_WD = 200; + +/** + * @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_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 TRUE. + * @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 FALSE. + * @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 TRUE. + * @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 TRUE. + * @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 TRUE. + * @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 TRUE. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +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 FALSE. + * @tc.size: SMALL + * @tc.type: FUNC + * @tc.level Level 1 + */ +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"; +} + +/** + * @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 srcFile = "invalid://data/test/src.txt"; + + auto res = CopyCore::ValidParams(srcFile, destFile); + 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 destFile = "invalid://data/test/dest.txt"; + + auto res = CopyCore::ValidParams(srcFile, destFile); + 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 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(); + + auto [errCode, infos] = CopyCore::CreateFileInfos(srcFile, destFile, options); + EXPECT_EQ(errCode, ERRNO_NOERR); + EXPECT_NE(infos, nullptr); + if (infos) { + EXPECT_FALSE(infos->hasListener); + EXPECT_EQ(infos->listener, nullptr); + EXPECT_EQ(infos->taskSignal, nullptr); + } + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_CreateFileInfos_001"; +} + +/** + * @tc.name: CopyCoreTest_CopySubDir_001 + * @tc.desc: Test function of CopyCore::CopySubDir interface for TRUE. + * @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"; + + string subDir = srcDir + "/sub_dir"; + mkdir(subDir.c_str(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + EXPECT_TRUE(false); + } + close(fd); + + 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)); + + 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_CopySubDir_002 + * @tc.desc: Test function of CopyCore::CopySubDir interface for TRUE. + * @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(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + EXPECT_TRUE(false); + } + 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 TRUE. + * @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(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + EXPECT_TRUE(false); + } + 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 TRUE. + * @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(), permission0755); + string subFile = subDir + "/sub_file.txt"; + int fd = open(subFile.c_str(), O_CREAT | O_RDWR, permission0644); + if (fd < 0) { + EXPECT_TRUE(false); + } + 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 TRUE. + * @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)); + 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 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 TRUE. + * @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_RegisterListener_002 + * @tc.desc: Test function of CopyCore::RegisterListener interface for the case when the info already exists in + * callbackMap_. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_RegisterListener_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_RegisterListener_002"; + + auto infos = make_shared(); + auto firstCallback = CopyCore::RegisterListener(infos); + EXPECT_NE(firstCallback, nullptr); + auto secondCallback = CopyCore::RegisterListener(infos); + EXPECT_EQ(secondCallback, 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_002"; +} + +/** + * @tc.name: CopyCoreTest_UnregisterListener_001 + * @tc.desc: Test function of CopyCore::UnregisterListener interface for TRUE. + * @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_UnregisterListener_002 + * @tc.desc: Test function of CopyCore::UnregisterListener interface for the case when the info is not registered in + * callbackMap_. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_UnregisterListener_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_UnregisterListener_002"; + + auto infos = make_shared(); + + 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_002"; +} + +/** + * @tc.name: CopyCoreTest_DoCopy_001 + * @tc.desc: Test function of CopyCore::DoCopy interface for FALSE. + * @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"; +} + +/** + * @tc.name: CopyCoreTest_DoCopy_002 + * @tc.desc: Test function of CopyCore::DoCopy interface for TRUE. + * @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()); + 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 TRUE. + * @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 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 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 TRUE. + * @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 TRUE. + * @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 TRUE. + * @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(); + event->wd = EXPECTED_WD; + 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); + + auto receiveInfo = make_shared(); + receiveInfo->path = testDir; + callback->wds.push_back({ UNEXPECTED_WD, receiveInfo }); + + auto event = make_unique(); + event->wd = EXPECTED_WD; + 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); + + auto receiveInfo = make_shared(); + receiveInfo->path = srcFile; + callback->wds.push_back({ EXPECTED_WD, receiveInfo }); + + auto event = make_unique(); + event->wd = EXPECTED_WD; + 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"; +} + +/** + * @tc.name: CopyCoreTest_OnFileReceive_001 + * @tc.desc: Test function of CopyCore::OnFileReceive interface fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_OnFileReceive_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_OnFileReceive_001"; + + auto infos = make_shared(); + CopyCore::OnFileReceive(infos); + EXPECT_TRUE(CopyCore::callbackMap_.empty()); + + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_OnFileReceive_001"; +} + +/** + * @tc.name: CopyCoreTest_OnFileReceive_002 + * @tc.desc: Test function of CopyCore::OnFileReceive interface when listener is nullptr. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyCoreTest, CopyCoreTest_OnFileReceive_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyCoreTest-begin CopyCoreTest_OnFileReceive_002"; + + auto infos = make_shared(); + auto callback = CopyCore::RegisterListener(infos); + CopyCore::OnFileReceive(infos); + EXPECT_NE(callback, nullptr); + if (callback) { + EXPECT_EQ(callback->listener, nullptr); + } + GTEST_LOG_(INFO) << "CopyCoreTest-end CopyCoreTest_OnFileReceive_002"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_dir_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_dir_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad9b034bbe2f62190612326f63bccdd83cae8cb6 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_dir_core_test.cpp @@ -0,0 +1,295 @@ +/* + * 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 "copy_dir_core.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class CopyDirCoreTest : public testing::Test { +public: + static filesystem::path g_srcPath; + static filesystem::path g_destPath; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + void CreateTestFile(const filesystem::path& path, const string& content = "test") + { + ofstream file(path); + file << content; + } +}; + +filesystem::path CopyDirCoreTest::g_srcPath; +filesystem::path CopyDirCoreTest::g_destPath; + +void CopyDirCoreTest::SetUpTestCase(void) +{ + g_srcPath = filesystem::temp_directory_path() / "src/"; + g_destPath = filesystem::temp_directory_path() / "dest/"; + filesystem::create_directory(g_srcPath); + filesystem::create_directory(g_destPath); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void CopyDirCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + filesystem::remove_all(g_srcPath); + filesystem::remove_all(g_destPath); +} + +void CopyDirCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void CopyDirCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_001 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with empty directory. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_001"; + + string src = g_srcPath.string() + "/test01"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_001"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_002 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with invalid mode. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_002"; + + string src = g_srcPath.string() + "/test02"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + + int invalidMode = COPYMODE_MAX + 1; + auto result = CopyDirCore::DoCopyDir(src, dest, optional(invalidMode)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_002"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_003 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with non-existent source. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_003"; + + string src = g_srcPath.string() + "/non_existent"; + string dest = g_destPath.string(); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_003"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_004 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with invalid destination. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_004"; + + string src = g_srcPath.string(); + string dest = g_destPath.string() + "/invalid_file.txt"; + filesystem::path(dest).remove_filename(); + filesystem::create_directories(filesystem::path(dest).parent_path()); + ofstream(dest).close(); // 创建文件而非目录 + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_004"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_005 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with same source and destination. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_005"; + + string src = g_srcPath.string(); + string dest = g_srcPath.string(); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_005"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_006 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with files. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_006"; + + string src = g_srcPath.string() + "/test06"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + CreateTestFile(src + "/file1.txt", "content1"); + CreateTestFile(src + "/file2.txt", "content2"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_006"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_007 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with subdirectories. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_007, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_007"; + + string src = g_srcPath.string() + "/test07"; + string dest = g_destPath.string(); + filesystem::create_directories(src + "/subdir1"); + filesystem::create_directories(src + "/subdir2"); + CreateTestFile(src + "/subdir1/file1.txt", "sub1_content1"); + CreateTestFile(src + "/subdir2/file2.txt", "sub2_content2"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_007"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_008 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with existing files (throw error mode). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_008, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_008"; + + string src = g_srcPath.string() + "/test08"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + CreateTestFile(src + "/file1.txt", "content1"); + + string destDir = dest + "/" + filesystem::path(src).filename().string(); + filesystem::create_directories(destDir); + CreateTestFile(destDir + "/file1.txt", "existing_content"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional(DIRMODE_FILE_COPY_THROW_ERR)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_TRUE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_008"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_009 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with existing files (overwrite mode). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_009, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_009"; + + string src = g_srcPath.string() + "/test09"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + CreateTestFile(src + "/file1.txt", "content1"); + + string destDir = dest + "/" + filesystem::path(src).filename().string(); + filesystem::create_directories(destDir); + CreateTestFile(destDir + "/file1.txt", "existing_content"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional(DIRMODE_FILE_COPY_REPLACE)); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_009"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp index af533602a0dff305542607889773d097d046636d..0988ca22a3815e325a40c453a109f469ee2d9630 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp @@ -23,7 +23,7 @@ using namespace testing; using namespace testing::ext; using namespace std; -class CopyFileCoreTest : public testing::Test { +class CopyFileCoreMockTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); @@ -32,40 +32,40 @@ public: static inline shared_ptr uvfs = nullptr; }; -void CopyFileCoreTest::SetUpTestCase(void) +void CopyFileCoreMockTest::SetUpTestCase(void) { uvfs = std::make_shared(); Uvfs::ins = uvfs; GTEST_LOG_(INFO) << "SetUpTestCase"; } -void CopyFileCoreTest::TearDownTestCase(void) +void CopyFileCoreMockTest::TearDownTestCase(void) { Uvfs::ins = nullptr; uvfs = nullptr; GTEST_LOG_(INFO) << "TearDownTestCase"; } -void CopyFileCoreTest::SetUp(void) +void CopyFileCoreMockTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; } -void CopyFileCoreTest::TearDown(void) +void CopyFileCoreMockTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_001 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_001 * @tc.desc: Test function of CopyFileCore::ValidMode interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_001, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_001"; FileInfo src; FileInfo dest; @@ -74,19 +74,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_001, testing::ext::TestSi auto res = CopyFileCore::DoCopyFile(src, dest, mode); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_001"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_003 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_003 * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_003, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_003, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_003"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_003"; FileInfo src; FileInfo dest; @@ -98,44 +98,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_003, testing::ext::TestSi auto res = CopyFileCore::DoCopyFile(src, dest); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_003"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_003"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_004 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_005 * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_004, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_005, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_004"; - - FileInfo src; - FileInfo dest; - src.isPath = true; - dest.isPath = false; - src.fdg = make_unique(1); - - EXPECT_CALL(*uvfs, uv_fs_open(_, _, _, _, _, _)).Times(1).WillOnce(Return(1)); - - auto res = CopyFileCore::DoCopyFile(src, dest); - EXPECT_EQ(res.IsSuccess(), false); - - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_004"; -} - -/** - * @tc.name: CopyFileCoreTest_DoCopyFile_005 - * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for FALSE. - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 1 - */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_005, testing::ext::TestSize.Level1) -{ - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_005"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_005"; FileInfo src; FileInfo dest; @@ -151,19 +126,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_005, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), false); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_005"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_005"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_006 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_006 * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_006, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_006, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_006"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_006"; FileInfo src; FileInfo dest; @@ -179,19 +154,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_006, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), true); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_006"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_006"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_007 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_007 * @tc.desc: Test function of CopyFileCore::OpenFile.TruncateCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_007, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_007, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_007"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_007"; FileInfo src; FileInfo dest; @@ -208,19 +183,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_007, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), false); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_007"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_007"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_008 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_008 * @tc.desc: Test function of CopyFileCore::OpenFile.TruncateCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_008, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_008, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_008"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_008"; FileInfo src; FileInfo dest; @@ -237,19 +212,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_008, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), false); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_008"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_008"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_009 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_009 * @tc.desc: Test function of CopyFileCore::OpenFile.TruncateCore interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_009, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_009, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_009"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_009"; FileInfo src; FileInfo dest; @@ -270,19 +245,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_009, testing::ext::TestSi close(srcfd); close(destfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_009"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_009"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0010 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0010 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for false. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0010, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0010, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0010"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0010"; FileInfo src; FileInfo dest; @@ -303,19 +278,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0010, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), false); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0010"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0010"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0011 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0011 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for false. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0011, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0011, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0011"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0011"; FileInfo src; FileInfo dest; @@ -336,19 +311,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0011, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), false); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0011"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0011"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0012 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0012 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0012, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0012, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0012"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0012"; FileInfo src; FileInfo dest; @@ -369,19 +344,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0012, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), true); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0012"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0012"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0013 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0013 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0013, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0013, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0013"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0013"; FileInfo src; FileInfo dest; @@ -402,7 +377,7 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0013, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), false); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0013"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0013"; } } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp index 8d14cda0e678a7535acb7e9908dc71075e572693..343446bc7fb3dabca537db9b70413d249fc8317d 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp @@ -22,7 +22,7 @@ using namespace testing; using namespace testing::ext; using namespace std; -class CopyFileCoreMockTest : public testing::Test { +class CopyFileCoreTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); @@ -30,36 +30,36 @@ public: void TearDown(); }; -void CopyFileCoreMockTest::SetUpTestCase(void) +void CopyFileCoreTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; } -void CopyFileCoreMockTest::TearDownTestCase(void) +void CopyFileCoreTest::TearDownTestCase(void) { GTEST_LOG_(INFO) << "TearDownTestCase"; } -void CopyFileCoreMockTest::SetUp(void) +void CopyFileCoreTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; } -void CopyFileCoreMockTest::TearDown(void) +void CopyFileCoreTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; } /** - * @tc.name: CopyFileCoreMockTest_DoCopyFile_001 + * @tc.name: CopyFileCoreTest_DoCopyFile_001 * @tc.desc: Test function of CopyFileCore::ValidMode interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_001, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_001"; FileInfo src; FileInfo dest; @@ -68,19 +68,19 @@ HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_001, testing::ext auto res = CopyFileCore::DoCopyFile(src, dest, mode); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_001"; } /** - * @tc.name: CopyFileCoreMockTest_DoCopyFile_002 + * @tc.name: CopyFileCoreTest_DoCopyFile_002 * @tc.desc: Test function of CopyFileCore::ValidMode interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_002, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_002, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_002"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_002"; FileInfo src; FileInfo dest; @@ -92,7 +92,7 @@ HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_002, testing::ext auto res = CopyFileCore::DoCopyFile(src, dest); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_002"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_002"; } } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/create_stream_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/create_stream_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..30e1ad522f563927a20f969a76150aae07f14b65 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/create_stream_core_test.cpp @@ -0,0 +1,81 @@ +/* +* 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 "create_stream_core.h" + +#define CREATE_STREAM_FILE_PATH "/data/test/CreateStreamCoreTest.txt" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +class CreateStreamCoreTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + int32_t fd = open(CREATE_STREAM_FILE_PATH, CREATE | O_RDWR, 0644); + close(fd); + }; + static void TearDownTestCase() + { + rmdir(CREATE_STREAM_FILE_PATH); + }; + void SetUp() {}; + void TearDown() {}; +}; +/** +* @tc.name: DoCreateStreamTest_0001 +* @tc.desc: Test function of DoCreateStream() interface for success. +* @tc.size: MEDIUM +* @tc.type: FUNC +* @tc.level Level 1 +*/ +HWTEST_F(CreateStreamCoreTest, DoCreateStreamTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CreateStreamCoreTest-begin DoCreateStreamTest_0001"; + auto ret = CreateStreamCore::DoCreateStream(CREATE_STREAM_FILE_PATH, "r"); + ASSERT_TRUE(ret.IsSuccess()); + + auto stream = ret.GetData().value(); + ASSERT_NE(stream, nullptr); + auto retClose = stream->Close(); + EXPECT_TRUE(retClose.IsSuccess()); + + GTEST_LOG_(INFO) << "CreateStreamCoreTest-end DoCreateStreamTest_0001"; +} + +/** +* @tc.name: DoCreateStreamTest_0002 +* @tc.desc: Test function of DoCreateStream() interface for fail. +* @tc.size: MEDIUM +* @tc.type: FUNC +* @tc.level Level 1 +*/ +HWTEST_F(CreateStreamCoreTest, DoCreateStreamTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CreateStreamCoreTest-begin DoCreateStreamTest_0002"; + auto ret = CreateStreamCore::DoCreateStream(CREATE_STREAM_FILE_PATH, "ssss"); + EXPECT_FALSE(ret.IsSuccess()); + + auto err = ret.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + + GTEST_LOG_(INFO) << "CreateStreamCoreTest-end DoCreateStreamTest_0002"; +} + +} +} +} \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/fdatasync_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/fdatasync_core_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6308de5056abc61308bd14e74bd42bec19f3003 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/fdatasync_core_mock_test.cpp @@ -0,0 +1,102 @@ +/* + * 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 "fdatasync_core.h" +#include "mock/uv_fs_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class FDataSyncCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +}; + +void FDataSyncCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + uvMock = std::make_shared(); + Uvfs::ins = uvMock; +} + +void FDataSyncCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + Uvfs::ins = nullptr; + uvMock = nullptr; +} + +void FDataSyncCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void FDataSyncCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FDataSyncCoreMockTest_DoFDataSync_001 + * @tc.desc: Test function of FDataSyncCore::DoFDataSync interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FDataSyncCoreMockTest, FDataSyncCoreMockTest_DoFDataSync_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FDataSyncCoreMockTest-begin FDataSyncCoreMockTest_DoFDataSync_001"; + + int fd = 3; + + EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(1)); + auto res = FDataSyncCore::DoFDataSync(fd); + EXPECT_EQ(res.IsSuccess(), true); + + GTEST_LOG_(INFO) << "FDataSyncCoreMockTest-end FDataSyncCoreMockTest_DoFDataSync_001"; +} + +/** + * @tc.name: FDataSyncCoreMockTest_DoFDataSync_002 + * @tc.desc: Test function of FDataSyncCore::DoFDataSync interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FDataSyncCoreMockTest, FDataSyncCoreMockTest_DoFDataSync_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FDataSyncCoreMockTest-begin FDataSyncCoreMockTest_DoFDataSync_002"; + + int fd = 3; + + EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(-1)); + auto res = FDataSyncCore::DoFDataSync(fd); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "FDataSyncCoreMockTest-end FDataSyncCoreMockTest_DoFDataSync_002"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/fdopen_stream_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/fdopen_stream_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3be0e56b9b560f55c53083aaf55ec9f77370aa8 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/fdopen_stream_core_test.cpp @@ -0,0 +1,117 @@ +/* +* 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 "fdopen_stream_core.h" + +#define FDOPEN_STREAM_FILE_PATH "/data/test/FdopenStreamCoreTest.txt" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +class FdopenStreamCoreTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + int32_t fd = open(FDOPEN_STREAM_FILE_PATH, CREATE | O_RDWR, 0644); + close(fd); + }; + static void TearDownTestCase() + { + rmdir(FDOPEN_STREAM_FILE_PATH); + }; + void SetUp() {}; + void TearDown() {}; +}; + +/** +* @tc.name: DoFdopenStreamTest_0001 +* @tc.desc: Test function of DoFdopenStream() interface for success. +* @tc.size: MEDIUM +* @tc.type: FUNC +* @tc.level Level 1 +*/ +HWTEST_F(FdopenStreamCoreTest, DoFdopenStreamTest_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FdopenStreamCoreTest-begin DoFdopenStreamTest_0001"; + int32_t fd = open(FDOPEN_STREAM_FILE_PATH, O_RDWR); + if (fd <= 0) { + close(fd); + ASSERT_TRUE(false); + } + + auto ret = FdopenStreamCore::DoFdopenStream(fd, "r"); + ASSERT_TRUE(ret.IsSuccess()); + + auto stream = ret.GetData().value(); + ASSERT_NE(stream, nullptr); + auto retClose = stream->Close(); + EXPECT_TRUE(retClose.IsSuccess()); + + close(fd); + + GTEST_LOG_(INFO) << "FdopenStreamCoreTest-end DoFdopenStreamTest_0001"; +} + +/** +* @tc.name: DoFdopenStreamTest_0002 +* @tc.desc: Test function of DoFdopenStream() interface for fd < 0. +* @tc.size: MEDIUM +* @tc.type: FUNC +* @tc.level Level 1 +*/ +HWTEST_F(FdopenStreamCoreTest, DoFdopenStreamTest_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FdopenStreamCoreTest-begin DoFdopenStreamTest_0002"; + auto ret = FdopenStreamCore::DoFdopenStream(-1, "r"); + EXPECT_FALSE(ret.IsSuccess()); + + auto err = ret.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + + GTEST_LOG_(INFO) << "FdopenStreamCoreTest-end DoFdopenStreamTest_0002"; +} + +/** +* @tc.name: DoFdopenStreamTest_0003 +* @tc.desc: Test function of DoFdopenStream() interface for fail. +* @tc.size: MEDIUM +* @tc.type: FUNC +* @tc.level Level 1 +*/ +HWTEST_F(FdopenStreamCoreTest, DoFdopenStreamTest_0003, testing::ext::TestSize.Level1) +{ + int32_t fd = open(FDOPEN_STREAM_FILE_PATH, O_RDWR); + if (fd <= 0) { + close(fd); + ASSERT_TRUE(false); + } + + GTEST_LOG_(INFO) << "FdopenStreamCoreTest-begin DoFdopenStreamTest_0003"; + auto ret = FdopenStreamCore::DoFdopenStream(fd, "sssssss"); + EXPECT_FALSE(ret.IsSuccess()); + + auto err = ret.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + + close(fd); + + GTEST_LOG_(INFO) << "FdopenStreamCoreTest-end DoFdopenStreamTest_0003"; +} + +} +} +} \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/fsync_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/fsync_core_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..688a5bca0c7b09d532602dee84d177ab87dc8008 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/fsync_core_mock_test.cpp @@ -0,0 +1,98 @@ +/* + * 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 "fsync_core.h" +#include "uv_fs_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class FsyncCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvfs = nullptr; +}; + +void FsyncCoreMockTest::SetUpTestCase(void) +{ + uvfs = std::make_shared(); + Uvfs::ins = uvfs; + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FsyncCoreMockTest::TearDownTestCase(void) +{ + Uvfs::ins = nullptr; + uvfs = nullptr; + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FsyncCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void FsyncCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FsyncCoreMockTest_DoFsync_001 + * @tc.desc: Test function of RenameCore::DoFsync interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsyncCoreMockTest, FsyncCoreMockTest_DoFsync_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsyncCoreMockTest-begin FsyncCoreMockTest_DoFsync_001"; + + EXPECT_CALL(*uvfs, uv_fs_fsync(_, _, _, _)).WillOnce(Return(-1)); + + auto res = FsyncCore::DoFsync(1); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "FsyncCoreMockTest-end FsyncCoreMockTest_DoFsync_001"; +} + +/** + * @tc.name: FsyncCoreMockTest_DoFsync_002 + * @tc.desc: Test function of RenameCore::DoFsync interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(FsyncCoreMockTest, FsyncCoreMockTest_DoFsync_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FsyncCoreMockTest-begin FsyncCoreMockTest_DoFsync_002"; + + EXPECT_CALL(*uvfs, uv_fs_fsync(_, _, _, _)).WillOnce(Return(1)); + + auto res = FsyncCore::DoFsync(1); + EXPECT_EQ(res.IsSuccess(), true); + + GTEST_LOG_(INFO) << "FsyncCoreMockTest-end FsyncCoreMockTest_DoFsync_002"; +} + + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/listfile_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/listfile_core_test.cpp index dbea771a41d6ea5c05ff61771b6489d5fe07886d..a919efebf8c14730016e73bbaa37041731c72903 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/listfile_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/listfile_core_test.cpp @@ -32,11 +32,11 @@ static void create_file(const fs::path& path, const std::vector& data, fs::create_directories(path.parent_path()); // 确保目录存在 std::ofstream file(path, binary ? std::ios::binary : std::ios::out); if (!file) { - GTEST_LOG_(INFO) << "create_directories failed"; + std::cerr << "创建文件失败: " << path << std::endl; return; } file.write(reinterpret_cast(data.data()), data.size()); - GTEST_LOG_(INFO) << "create_directories success"; + std::cout << "已创建文件: " << path << std::endl; } static void WriteBuffer(const string filename) @@ -90,7 +90,6 @@ public: * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0001, testing::ext::TestSize.Level1) { @@ -117,7 +116,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0001, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0002, testing::ext::TestSize.Level1) { @@ -144,7 +142,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0002, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0003, testing::ext::TestSize.Level1) { @@ -167,7 +164,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0003, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0004, testing::ext::TestSize.Level1) { @@ -195,7 +191,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0004, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0005, testing::ext::TestSize.Level1) { @@ -223,7 +218,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0005, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0006, testing::ext::TestSize.Level1) { @@ -251,7 +245,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0006, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0007, testing::ext::TestSize.Level1) { @@ -278,7 +271,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0007, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0008, testing::ext::TestSize.Level1) { @@ -305,7 +297,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0008, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0009, testing::ext::TestSize.Level1) { @@ -330,7 +321,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0009, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0010, testing::ext::TestSize.Level1) { @@ -355,7 +345,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0010, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0011, testing::ext::TestSize.Level1) { @@ -379,7 +368,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0011, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0012, testing::ext::TestSize.Level1) { @@ -399,7 +387,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0012, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0013, testing::ext::TestSize.Level1) { @@ -422,7 +409,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0013, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0014, testing::ext::TestSize.Level1) { @@ -442,7 +428,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0014, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0015, testing::ext::TestSize.Level1) { @@ -476,7 +461,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0015, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0016, testing::ext::TestSize.Level1) { @@ -503,7 +487,6 @@ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0016, testing::ext::TestSize.Level * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 -* @tc.require: AR000IGDNF */ HWTEST_F(ListFileCoreTest, DoListFileCoreTest_0017, testing::ext::TestSize.Level1) { diff --git a/interfaces/test/unittest/js/mod_fs/properties/lseek_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/lseek_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5bd78bb77018d123fb886b8ee6120119131e892 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/lseek_core_test.cpp @@ -0,0 +1,115 @@ +/* + * 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 "lseek_core.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class LseekCoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void LseekCoreTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void LseekCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void LseekCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void LseekCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: LseekCoreTest_DoLseek_001 + * @tc.desc: Test function of LseekCore::DoLseek interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(LseekCoreTest, LseekCoreTest_DoLseek_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "LseekCoreTest-begin LseekCoreTest_DoLseek_001"; + + int32_t fd = -1; + int64_t offset = 0; + + auto res = LseekCore::DoLseek(fd, offset); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "LseekCoreTest-end LseekCoreTest_DoLseek_001"; +} + +/** + * @tc.name: LseekCoreTest_DoLseek_002 + * @tc.desc: Test function of LseekCore::DoLseek interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(LseekCoreTest, LseekCoreTest_DoLseek_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "LseekCoreTest-begin LseekCoreTest_DoLseek_002"; + + int32_t fd = 1; + int64_t offset = 0; + optional pos = std::make_optional(static_cast(-1)); + + auto res = LseekCore::DoLseek(fd, offset, pos); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "LseekCoreTest-end LseekCoreTest_DoLseek_002"; +} + +/** + * @tc.name: LseekCoreTest_DoLseek_003 + * @tc.desc: Test function of LseekCore::DoLseek interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(LseekCoreTest, LseekCoreTest_DoLseek_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "LseekCoreTest-begin LseekCoreTest_DoLseek_003"; + + int32_t fd = 1; + int64_t offset = 0; + optional pos = std::make_optional(SeekPos::CURRENT); + + auto res = LseekCore::DoLseek(fd, offset, pos); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "LseekCoreTest-end LseekCoreTest_DoLseek_003"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/mkdir_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/mkdir_core_mock_test.cpp index c70674062ff3e1a6ae52e603d7601f43d8fb48b3..9c5bc778902d4b1b8dbe6968a57492af90444ad2 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mkdir_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/mkdir_core_mock_test.cpp @@ -15,11 +15,11 @@ #include #include -#include #include +#include #include "mkdir_core.h" -#include "mock/uv_fs_mock.h" +#include "uv_fs_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; @@ -107,7 +107,7 @@ HWTEST_F(MkdirCoreMockTest, MkdirCoreMockTest_DoMkdir_0002, testing::ext::TestSi /** * @tc.name: MkdirCoreMockTest_DoMkdir_0003 - * @tc.desc: Test function of DoMkdir() interface for FAILED. + * @tc.desc: Test function of DoMkdir() interface is FAILED for uv_fs_mkdir return 1. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -127,7 +127,7 @@ HWTEST_F(MkdirCoreMockTest, MkdirCoreMockTest_DoMkdir_0003, testing::ext::TestSi /** * @tc.name: MkdirCoreMockTest_DoMkdir_0004 - * @tc.desc: Test function of DoMkdir() interface for FAILED. + * @tc.desc: Test function of DoMkdir() interface is FAILED for file exists. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -152,7 +152,7 @@ HWTEST_F(MkdirCoreMockTest, MkdirCoreMockTest_DoMkdir_0004, testing::ext::TestSi /** * @tc.name: MkdirCoreMockTest_DoMkdir_0005 - * @tc.desc: Test function of DoMkdir() interface for FAILED. + * @tc.desc: Test function of DoMkdir() interface is FAILED for no such file or directory. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 diff --git a/interfaces/test/unittest/js/mod_fs/properties/mkdtemp_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/mkdtemp_core_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d207773deb768fc5acb9e3cabaf71dddbfd3ac57 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/mkdtemp_core_mock_test.cpp @@ -0,0 +1,114 @@ +/* + * 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 "mkdtemp_core.h" +#include "mock/uv_fs_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class MkdtempCoreMockTest : public testing::Test { +public: + static filesystem::path tempFilePath; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +}; + +filesystem::path MkdtempCoreMockTest::tempFilePath; + +void MkdtempCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + tempFilePath = filesystem::temp_directory_path() / "test"; + std::filesystem::create_directory(tempFilePath); + uvMock = std::make_shared(); + Uvfs::ins = uvMock; +} + +void MkdtempCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + filesystem::remove_all(tempFilePath); + Uvfs::ins = nullptr; + uvMock = nullptr; +} + +void MkdtempCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void MkdtempCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: MkdtempCoreMockTest_DoMkdtemp_0001 + * @tc.desc: Test function of DoMkdtemp() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MkdtempCoreMockTest, MkdtempCoreMockTest_DoMkdtemp_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MkdtempCoreMockTest-begin MkdtempCoreMockTest_DoMkdtemp_0001"; + + uv_fs_t mock_req; + mock_req.path = const_cast("/data/local/tmp/test/XXXXXX"); + + EXPECT_CALL(*uvMock, uv_fs_mkdtemp(_, _, _, _)) + .WillOnce(Invoke([&](uv_loop_t*, uv_fs_t* req, const char*, uv_fs_cb) { + *req = mock_req; + return 0; + })); + + auto ret = MkdtempCore::DoMkdtemp("/data/local/tmp/test/XXXXXX"); + EXPECT_EQ(ret.IsSuccess(), true); + + GTEST_LOG_(INFO) << "MkdtempCoreMockTest-end MkdtempCoreMockTest_DoMkdtemp_0001"; +} + +/** + * @tc.name: MkdtempCoreMockTest_DoMkdtemp_0002 + * @tc.desc: Test function of DoMkdtemp() interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MkdtempCoreMockTest, MkdtempCoreMockTest_DoMkdtemp_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MkdtempCoreMockTest-begin MkdtempCoreMockTest_DoMkdtemp_0002"; + + string path = tempFilePath.string() + "/XXXXXX"; + + EXPECT_CALL(*uvMock, uv_fs_mkdtemp(_, _, _, _)).WillOnce(Return(-1)); + auto ret = MkdtempCore::DoMkdtemp(path); + EXPECT_EQ(ret.IsSuccess(), false); + + GTEST_LOG_(INFO) << "MkdtempCoreMockTest-end MkdtempCoreMockTest_DoMkdtemp_0002"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.cpp b/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.cpp index 5878a93046576b034577b1d1431decb895cdb2dc..189edf92599772425b33d99a345c8eeb235cc9a7 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.cpp @@ -23,7 +23,7 @@ int setxattr(const char *path, const char *name, const void *value, size_t size, return System::ins->setxattr(path, name, value, size, flags); } -int getxattr(const char *path, const char *name, void *value, size_t size) +ssize_t getxattr(const char *path, const char *name, void *value, size_t size) { return System::ins->getxattr(path, name, value, size); } diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.h b/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.h index 3ff74be78027d70a93550e1fbb0a4d59a0331885..dad578b09d80aa9ee77b2760394b852e2b23eaf3 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.h +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/system_mock.h @@ -29,7 +29,7 @@ public: public: virtual ~System() = default; virtual int setxattr(const char *path, const char *name, const void *value, size_t size, int flags) = 0; - virtual int getxattr(const char *path, const char *name, void *value, size_t size) = 0; + virtual ssize_t getxattr(const char *path, const char *name, void *value, size_t size) = 0; virtual int fgetxattr(int filedes, const char *name, void *value, size_t size) = 0; virtual int flock(int fd, int operation) = 0; }; @@ -37,7 +37,7 @@ public: class SystemMock : public System { public: MOCK_METHOD5(setxattr, int(const char *path, const char *name, const void *value, size_t size, int flags)); - MOCK_METHOD4(getxattr, int(const char *path, const char *name, void *value, size_t size)); + MOCK_METHOD4(getxattr, ssize_t(const char *path, const char *name, void *value, size_t size)); MOCK_METHOD4(fgetxattr, int(int filedes, const char *name, void *value, size_t size)); MOCK_METHOD2(flock, int(int fd, int operation)); }; diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.cpp b/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.cpp index b656a1ad103d4e47cc0346e49b7d1fc1e074035c..2a13ecf69c515e88b62f825510e79d4a160dfcab 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.cpp @@ -13,10 +13,8 @@ * limitations under the License. */ - #include "uv_fs_mock.h" - using namespace OHOS::FileManagement::ModuleFileIO; int uv_fs_read(uv_loop_t *loop, uv_fs_t *req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t off, @@ -55,9 +53,9 @@ int uv_fs_rmdir(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb) return Uvfs::ins->uv_fs_rmdir(loop, req, path, cb); } -int uv_fs_symlink(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, int flags, uv_fs_cb cb) +int uv_fs_symlink(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *newPath, int flags, uv_fs_cb cb) { - return Uvfs::ins->uv_fs_symlink(loop, req, path, new_path, flags, cb); + return Uvfs::ins->uv_fs_symlink(loop, req, path, newPath, flags, cb); } int uv_fs_open(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, int mode, uv_fs_cb cb) @@ -134,4 +132,4 @@ int uv_fs_sendfile(uv_loop_t *loop, uv_fs_t *req, uv_file outFd, uv_file inFd, i int uv_fs_lstat(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb) { return Uvfs::ins->uv_fs_lstat(loop, req, path, cb); -} \ No newline at end of file +} diff --git a/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.h b/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.h index 1fa703a0fe7ba997c03ec58c580c35c2220b40a8..0bcfa87a5d099d90efc30f570bf7499d8e2e1253 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.h +++ b/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef UV_FS_READ_MOCK_H -#define UV_FS_READ_MOCK_H +#ifndef INTERFACES_TEST_UNITTEST_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H +#define INTERFACES_TEST_UNITTEST_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H #include "uv.h" @@ -25,6 +25,7 @@ namespace OHOS::FileManagement::ModuleFileIO { class Uvfs { public: static inline std::shared_ptr ins = nullptr; + public: virtual ~Uvfs() = default; virtual int uv_fs_read(uv_loop_t *loop, uv_fs_t *req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, @@ -36,7 +37,7 @@ public: virtual int uv_fs_scandir(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, uv_fs_cb cb) = 0; virtual int uv_fs_scandir_next(uv_fs_t *req, uv_dirent_t *ent) = 0; virtual int uv_fs_rmdir(uv_loop_t *loop, uv_fs_t *req, const char* path, uv_fs_cb cb) = 0; - virtual int uv_fs_symlink(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, int flags, + virtual int uv_fs_symlink(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *newPath, int flags, uv_fs_cb cb) = 0; virtual int uv_fs_open(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, int mode, uv_fs_cb cb) = 0; virtual int uv_fs_ftruncate(uv_loop_t *loop, uv_fs_t *req, uv_file fd, int64_t offset, uv_fs_cb cb) = 0; @@ -50,9 +51,9 @@ public: virtual int uv_fs_mkdtemp(uv_loop_t *loop, uv_fs_t *req, const char *tpl, uv_fs_cb cb) = 0; virtual int uv_fs_unlink(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb) = 0; virtual int uv_fs_rename(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *newPath, uv_fs_cb cb) = 0; - virtual int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) = 0; - virtual int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file outFd, uv_file inFd, - int64_t off, size_t len, uv_fs_cb cb) = 0; + virtual int uv_fs_fsync(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) = 0; + virtual int uv_fs_sendfile(uv_loop_t *loop, uv_fs_t *req, uv_file outFd, uv_file inFd, int64_t off, size_t len, + uv_fs_cb cb) = 0; virtual int uv_fs_lstat(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb) = 0; }; @@ -67,7 +68,7 @@ public: MOCK_METHOD5(uv_fs_scandir, int(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, uv_fs_cb cb)); MOCK_METHOD2(uv_fs_scandir_next, int(uv_fs_t *req, uv_dirent_t *ent)); MOCK_METHOD4(uv_fs_rmdir, int(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)); - MOCK_METHOD6(uv_fs_symlink, int(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *new_path, int flags, + MOCK_METHOD6(uv_fs_symlink, int(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *newPath, int flags, uv_fs_cb cb)); MOCK_METHOD6(uv_fs_open, int(uv_loop_t *loop, uv_fs_t *req, const char *path, int flags, int mode, uv_fs_cb cb)); MOCK_METHOD5(uv_fs_ftruncate, int(uv_loop_t *loop, uv_fs_t *req, uv_file fd, int64_t offset, uv_fs_cb cb)); @@ -81,11 +82,11 @@ public: MOCK_METHOD4(uv_fs_mkdtemp, int(uv_loop_t *loop, uv_fs_t *req, const char *tpl, uv_fs_cb cb)); MOCK_METHOD4(uv_fs_unlink, int(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)); MOCK_METHOD5(uv_fs_rename, int(uv_loop_t *loop, uv_fs_t *req, const char *path, const char *newPath, uv_fs_cb cb)); - MOCK_METHOD4(uv_fs_fsync, int(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)); - MOCK_METHOD7(uv_fs_sendfile, int(uv_loop_t* loop, uv_fs_t* req, uv_file outFd, uv_file inFd, - int64_t off, size_t len, uv_fs_cb cb)); + MOCK_METHOD4(uv_fs_fsync, int(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb)); + MOCK_METHOD7(uv_fs_sendfile, int(uv_loop_t *loop, uv_fs_t *req, uv_file outFd, uv_file inFd, int64_t off, + size_t len, uv_fs_cb cb)); MOCK_METHOD4(uv_fs_lstat, int(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb)); }; -} // OHOS::FileManagement::ModuleFileIO -#endif \ No newline at end of file +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_TEST_UNITTEST_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/movedir_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/movedir_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3e578db2ea065306e7000bb34f8871f6e3c7ec46 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/movedir_core_test.cpp @@ -0,0 +1,333 @@ +/* + * 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 "movedir_core.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class MoveDirCoreTest : public testing::Test { +public: + static filesystem::path srcPath; + static filesystem::path destPath; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +filesystem::path MoveDirCoreTest::srcPath; +filesystem::path MoveDirCoreTest::destPath; + +void MoveDirCoreTest::SetUpTestCase(void) +{ + srcPath = filesystem::temp_directory_path() / "src/"; + destPath = filesystem::temp_directory_path() / "dest/"; + std::filesystem::create_directory(srcPath); + std::filesystem::create_directory(destPath); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void MoveDirCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + filesystem::remove_all(srcPath); + filesystem::remove_all(destPath); +} + +void MoveDirCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void MoveDirCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0001 + * @tc.desc: Test function of DoMoveDir() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0001"; + + string src = srcPath.string() + "/test01"; + string dest = destPath.string(); + filesystem::create_directories(src); + + auto result = MoveDirCore::DoMoveDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0001"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0002 + * @tc.desc: Test function of DoMoveDir() interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0002"; + + string src = srcPath.string() + "/test02"; + string dest = destPath.string(); + filesystem::create_directories(src); + + int invalidMode = DIRMODE_MAX + 1; + auto result = MoveDirCore::DoMoveDir(src, dest, optional(invalidMode)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + auto err = result.fsResult.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0002"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0003 + * @tc.desc: Test function of DoMoveDir() interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0002"; + + string src = srcPath.string() + "/test03"; + string dest = destPath.string(); + + auto result = MoveDirCore::DoMoveDir(src, dest, optional(DIRMODE_DIRECTORY_REPLACE)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + auto err = result.fsResult.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0003"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0004 + * @tc.desc: Test function of DoMoveDir() interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0002"; + + string src = srcPath.string(); + string dest = destPath.string() + "/test04"; + + auto result = MoveDirCore::DoMoveDir(src, dest, optional(DIRMODE_DIRECTORY_REPLACE)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + auto err = result.fsResult.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900020); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0004"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0005 + * @tc.desc: Test function of DoMoveDir() interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0005"; + + string src = "/data/local/test05/src/src/src/test05"; + string dest = destPath.string() + "/src"; + filesystem::create_directories(src); + filesystem::create_directories(dest); + + auto result = MoveDirCore::DoMoveDir( + "/data/local/test05/", destPath.string(), optional(DIRMODE_DIRECTORY_THROW_ERR)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + auto err = result.fsResult.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900032); + EXPECT_FALSE(result.errFiles.has_value()); + + filesystem::remove_all("/data/local/test05"); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0005"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0006 + * @tc.desc: Test function of DoMoveDir() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0006"; + + string src = "/data/local/test06/src/src/src/test06"; + string dest = destPath.string() + "/src"; + filesystem::create_directories(src); + filesystem::create_directories(dest); + + auto result = MoveDirCore::DoMoveDir( + "/data/local/test06/src", destPath.string(), optional(DIRMODE_DIRECTORY_REPLACE)); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + + filesystem::remove_all("/data/local/test06"); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0006"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0007 + * @tc.desc: Test function of DoMoveDir() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0007, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0007"; + + filesystem::create_directories("/data/local/test07/src"); + filesystem::create_directories("/data/local/test07/dest"); + filesystem::path srcFile = "/data/local/test07/src/test_file.txt"; + ofstream(srcFile) << "Test content\n123\n456"; + filesystem::path destFile = "/data/local/test07/dest/test_file.txt"; + ofstream(destFile) << "Test content\ndest"; + + auto result = MoveDirCore::DoMoveDir( + "/data/local/test07/src/", "/data/local/test07/dest/", optional(DIRMODE_FILE_THROW_ERR)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + auto err = result.fsResult.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900015); + EXPECT_TRUE(result.errFiles.has_value()); + + filesystem::remove_all("/data/local/test07"); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0007"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0008 + * @tc.desc: Test function of DoMoveDir() interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0008, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0008"; + + filesystem::create_directories("/data/local/test08/src"); + filesystem::create_directories("/data/local/test08/dest/test_file/test_file"); + filesystem::path srcFile = "/data/local/test08/src/test_file"; + ofstream(srcFile) << "Test content\n123\n456"; + + auto result = MoveDirCore::DoMoveDir( + "/data/local/test08/src/", "/data/local/test08/dest/test_file/", optional(DIRMODE_FILE_REPLACE)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_TRUE(result.errFiles.has_value()); + + filesystem::remove_all("/data/local/test08"); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0008"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0009 + * @tc.desc: Test function of DoMoveDir() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0009, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0009"; + + filesystem::create_directories("/data/local/test09/src"); + filesystem::create_directories("/data/local/test09/dest"); + filesystem::path srcFile = "/data/local/test09/src/test_file.txt"; + ofstream(srcFile) << "Test content\n123\n456"; + filesystem::path destFile = "/data/local/test09/dest/test_file.txt"; + ofstream(destFile) << "Test content\ndest"; + + auto result = MoveDirCore::DoMoveDir( + "/data/local/test09/src/", "/data/local/test09/dest/", optional(DIRMODE_FILE_REPLACE)); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + filesystem::remove_all("/data/local/test09"); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0009"; +} + +/** + * @tc.name: MoveDirCoreTest_DoMoveDir_0010 + * @tc.desc: Test function of DoMoveDir() interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(MoveDirCoreTest, MoveDirCoreTest_DoMoveDir_0010, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "MoveDirCoreTest-begin MoveDirCoreTest_DoMoveDir_0010"; + + filesystem::create_directories("/data/local/test09/src/test_file.txt"); + filesystem::create_directories("/data/local/test09/dest"); + filesystem::path destFile = "/data/local/test09/dest/test_file.txt"; + ofstream(destFile) << "Test content\ndest"; + + auto result = MoveDirCore::DoMoveDir( + "/data/local/test09/src/", "/data/local/test09/dest/", optional(DIRMODE_FILE_REPLACE)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_TRUE(result.errFiles.has_value()); + + filesystem::remove_all("/data/local/test09"); + + GTEST_LOG_(INFO) << "MoveDirCoreTest-end MoveDirCoreTest_DoMoveDir_0010"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file 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 27cd727317dfc6a63ef724b06f2bd75f3fce3844..abee054b152c8a12d34f38dc4139ced3352f8da4 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 "open_core.h" -#include "mock/uv_fs_mock.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; }; @@ -40,6 +43,7 @@ void OpenCoreMockTest::SetUpTestCase(void) GTEST_LOG_(INFO) << "SetUpTestCase"; uvMock = std::make_shared(); Uvfs::ins = uvMock; + UnistdMock::EnableMock(); } void OpenCoreMockTest::TearDownTestCase(void) @@ -47,6 +51,7 @@ void OpenCoreMockTest::TearDownTestCase(void) GTEST_LOG_(INFO) << "TearDownTestCase"; Uvfs::ins = nullptr; uvMock = nullptr; + UnistdMock::DisableMock(); } void OpenCoreMockTest::SetUp(void) @@ -60,19 +65,19 @@ void OpenCoreMockTest::TearDown(void) } /** -* @tc.name: OpenCoreMockTest_DoOpen_001 -* @tc.desc: Test function of OpenCore::DoOpen interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreMockTest_DoOpen_001 + * @tc.desc: Test function of OpenCore::DoOpen interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_001, testing::ext::TestSize.Level1) { 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); @@ -81,59 +86,67 @@ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_001, testing::ext::TestSize.L } /** -* @tc.name: OpenCoreMockTest_DoOpen_002 -* @tc.desc: Test function of OpenCore::DoOpen interface for SUCCESS. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreMockTest_DoOpen_002 + * @tc.desc: Test function of OpenCore::DoOpen interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_002, testing::ext::TestSize.Level1) { 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"; } /** -* @tc.name: OpenCoreMockTest_DoOpen_003 -* @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreMockTest_DoOpen_003 + * @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_003, testing::ext::TestSize.Level1) { 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"; } /** -* @tc.name: OpenCoreMockTest_DoOpen_004 -* @tc.desc: Test function of OpenCore::DoOpen interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreMockTest_DoOpen_004 + * @tc.desc: Test function of OpenCore::DoOpen interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreMockTest, OpenCoreMockTest_DoOpen_004, testing::ext::TestSize.Level1) { 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/open_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/open_core_test.cpp index fcfc9019b4a768a80bbbf34f09202a4ef474340b..a6cad138a535dfdc7f4779fc5991572ea60e2f8f 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/open_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/open_core_test.cpp @@ -13,10 +13,10 @@ * limitations under the License. */ -#include - #include "open_core.h" +#include + namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; using namespace testing::ext; @@ -51,12 +51,12 @@ void OpenCoreTest::TearDown(void) } /** -* @tc.name: OpenCoreTest_DoOpen_001 -* @tc.desc: Test function of OpenCore::DoOpen interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_001 + * @tc.desc: Test function of OpenCore::DoOpen interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_001, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_001"; @@ -71,12 +71,12 @@ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_001, testing::ext::TestSize.Level1) } /** -* @tc.name: OpenCoreTest_DoOpen_002 -* @tc.desc: Test function of OpenCore::DoOpen interface for ERROR. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_002 + * @tc.desc: Test function of OpenCore::DoOpen interface for ERROR. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_002, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_002"; @@ -91,12 +91,12 @@ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_002, testing::ext::TestSize.Level1) } /** -* @tc.name: OpenCoreTest_DoOpen_003 -* @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_003 + * @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_003, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_003"; @@ -111,12 +111,12 @@ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_003, testing::ext::TestSize.Level1) } /** -* @tc.name: OpenCoreTest_DoOpen_004 -* @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_004 + * @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_004, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_004"; @@ -131,12 +131,12 @@ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_004, testing::ext::TestSize.Level1) } /** -* @tc.name: OpenCoreTest_DoOpen_005 -* @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_005 + * @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_005, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_005"; @@ -151,12 +151,12 @@ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_005, testing::ext::TestSize.Level1) } /** -* @tc.name: OpenCoreTest_DoOpen_006 -* @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_006 + * @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_006, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_006"; @@ -171,12 +171,12 @@ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_006, testing::ext::TestSize.Level1) } /** -* @tc.name: OpenCoreTest_DoOpen_007 -* @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. -* @tc.size: MEDIUM -* @tc.type: FUNC -* @tc.level Level 1 -*/ + * @tc.name: OpenCoreTest_DoOpen_007 + * @tc.desc: Test function of OpenCore::DoOpen interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ HWTEST_F(OpenCoreTest, OpenCoreTest_DoOpen_007, testing::ext::TestSize.Level1) { GTEST_LOG_(INFO) << "OpenCoreTest-begin OpenCoreTest_DoOpen_007"; diff --git a/interfaces/test/unittest/js/mod_fs/properties/stat_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/stat_core_mock_test.cpp index 2fd8bd7f5a0fc91f34abf631095019ddbb5e7a9f..2a3133bdbce145d0e2c577947f3aba8383b3528e 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/stat_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/stat_core_mock_test.cpp @@ -13,10 +13,10 @@ * limitations under the License. */ -#include "securec.h" #include "stat_core.h" #include "uv_fs_mock.h" +#include #include namespace OHOS::FileManagement::ModuleFileIO::Test { @@ -59,7 +59,7 @@ void StatCoreMockTest::TearDown(void) /** * @tc.name: StatCoreMockTest_DoStat_001 - * @tc.desc: Test function of FsyncCore::DoStat interface for FALSE. + * @tc.desc: Test function of StatCore::DoStat interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -82,7 +82,7 @@ HWTEST_F(StatCoreMockTest, StatCoreMockTest_DoStat_001, testing::ext::TestSize.L /** * @tc.name: StatCoreMockTest_DoStat_002 - * @tc.desc: Test function of FsyncCore::DoStat interface for FALSE. + * @tc.desc: Test function of StatCore::DoStat interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -105,7 +105,7 @@ HWTEST_F(StatCoreMockTest, StatCoreMockTest_DoStat_002, testing::ext::TestSize.L /** * @tc.name: StatCoreMockTest_DoStat_003 - * @tc.desc: Test function of FsyncCore::DoStat interface for FALSE. + * @tc.desc: Test function of StatCore::DoStat interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -127,30 +127,27 @@ HWTEST_F(StatCoreMockTest, StatCoreMockTest_DoStat_003, testing::ext::TestSize.L } /** - * @tc.name: StatCoreMockTest_DoStat_005 - * @tc.desc: Test function of FsyncCore::DoStat interface for FALSE. + * @tc.name: StatCoreMockTest_DoStat_004 + * @tc.desc: Test function of StatCore::DoStat interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(StatCoreMockTest, StatCoreMockTest_DoStat_005, testing::ext::TestSize.Level1) +HWTEST_F(StatCoreMockTest, StatCoreMockTest_DoStat_004, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "StatCoreMockTest-begin StatCoreMockTest_DoStat_005"; + GTEST_LOG_(INFO) << "StatCoreMockTest-begin StatCoreMockTest_DoStat_004"; FileInfo fileinfo; - string buffer = "Hello, World!"; - int pathLength = buffer.size() + 1; - fileinfo.path = std::make_unique(pathLength); - memcpy_s(fileinfo.path.get(), pathLength, buffer.c_str(), buffer.size()); - fileinfo.fdg = std::make_unique(-1); - fileinfo.isPath = true; + fileinfo.path = std::make_unique(1); + fileinfo.fdg = std::make_unique(1); + fileinfo.isPath = false; EXPECT_CALL(*uvfs, uv_fs_stat(_, _, _, _)).WillOnce(Return(-1)); auto res = StatCore::DoStat(fileinfo); - EXPECT_EQ(res.IsSuccess(), false); + EXPECT_EQ(res.IsSuccess(), true); - GTEST_LOG_(INFO) << "StatCoreMockTest-end StatCoreMockTest_DoStat_005"; + GTEST_LOG_(INFO) << "StatCoreMockTest-end StatCoreMockTest_DoStat_004"; } } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/stat_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/stat_core_test.cpp index 5ad93fbf97b015b70ea49f13ee7815935ddb768e..f11d9262518091ff2b8b97ac00e2ae17df41317d 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/stat_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/stat_core_test.cpp @@ -52,7 +52,7 @@ void StatCoreTest::TearDown(void) /** * @tc.name: StatCoreTest_DoStat_001 - * @tc.desc: Test function of FsyncCore::DoStat interface for FALSE. + * @tc.desc: Test function of StatCore::DoStat interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 @@ -71,7 +71,7 @@ HWTEST_F(StatCoreTest, StatCoreTest_DoStat_001, testing::ext::TestSize.Level1) /** * @tc.name: StatCoreTest_DoStat_002 - * @tc.desc: Test function of FsyncCore::DoStat interface for FALSE. + * @tc.desc: Test function of StatCore::DoStat interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 diff --git a/interfaces/test/unittest/js/mod_fs/properties/symlink_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/symlink_core_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd6e4b43b79db6a533e5d3c026777373580cc4cd --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/symlink_core_mock_test.cpp @@ -0,0 +1,104 @@ +/* + * 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 "symlink_core.h" +#include "uv_fs_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class SymlinkCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +}; + +void SymlinkCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + uvMock = std::make_shared(); + Uvfs::ins = uvMock; +} + +void SymlinkCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + Uvfs::ins = nullptr; + uvMock = nullptr; +} + +void SymlinkCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void SymlinkCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: SymlinkCoreMockTest_DoSymlink_001 + * @tc.desc: Test function of SymlinkCore::DoSymlink interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(SymlinkCoreMockTest, SymlinkCoreMockTest_DoSymlink_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "SymlinkCore-begin SymlinkCoreMockTest_DoSymlink_001"; + + string target; + string srcPath; + + EXPECT_CALL(*uvMock, uv_fs_symlink(_, _, _, _, _, _)).WillOnce(Return(-1)); + + auto res = SymlinkCore::DoSymlink(target, srcPath); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "SymlinkCore-end SymlinkCoreMockTest_DoSymlink_001"; +} + +/** + * @tc.name: SymlinkCoreMockTest_DoSymlink_002 + * @tc.desc: Test function of SymlinkCore::DoSymlink interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(SymlinkCoreMockTest, SymlinkCoreMockTest_DoSymlink_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "SymlinkCore-begin SymlinkCoreMockTest_DoSymlink_002"; + + string target; + string srcPath; + + EXPECT_CALL(*uvMock, uv_fs_symlink(_, _, _, _, _, _)).WillOnce(Return(1)); + + auto res = SymlinkCore::DoSymlink(target, srcPath); + EXPECT_EQ(res.IsSuccess(), true); + + GTEST_LOG_(INFO) << "SymlinkCore-end SymlinkCoreMockTest_DoSymlink_002"; +} + +} // OHOS::FileManagement::ModuleFileIO::Test 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 0000000000000000000000000000000000000000..7b582b51cb71e8b2810f800f8e4840b8feb3f354 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_mock_test.cpp @@ -0,0 +1,238 @@ +/* + * 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" +#include "unistd_mock.h" + +using namespace OHOS; +using namespace OHOS::Storage::DistributedFile; + +class MockDistributedFileDaemonManager final : public DistributedFileDaemonManager { +public: + 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 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 CancelCopyTask(const std::string &sessionName) override + { + return 0; + } + 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; + } + + + MockDistributedFileDaemonManager() = default; + ~MockDistributedFileDaemonManager() = default; + +public: + static std::shared_ptr GetMock(); + static void DisableMock(); + +private: + static thread_local std::shared_ptr managerMock; +}; + +thread_local std::shared_ptr MockDistributedFileDaemonManager::managerMock = nullptr; + +std::shared_ptr MockDistributedFileDaemonManager::GetMock() +{ + if (managerMock == nullptr) { + managerMock = std::make_shared(); + } + return managerMock; +} + +void MockDistributedFileDaemonManager::DisableMock() +{ + managerMock = nullptr; +} + +class MockTaskSignalListener : public OHOS::DistributedFS::ModuleTaskSignal::TaskSignalListener { +public: + MOCK_METHOD(void, OnCancel, (), (override)); +}; + +#ifdef ENABLE_DISTRIBUTED_FILE_MOCK +DistributedFileDaemonManager &DistributedFileDaemonManager::GetInstance() +{ + return *MockDistributedFileDaemonManager::GetMock(); +} +#endif + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +string g_path = "/data/test/TransListenerCoreMockTest.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 TransListenerCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +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); + UnistdMock::EnableMock(); +} + +void TransListenerCoreMockTest::TearDownTestCase(void) +{ + rmdir(g_path.c_str()); + MockDistributedFileDaemonManager::DisableMock(); + UnistdMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void TransListenerCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void TransListenerCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @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(TransListenerCoreMockTest, TransListenerCoreMockTest_PrepareCopySession_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreMockTest-begin TransListenerCoreMockTest_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"; + auto unistdMock = UnistdMock::GetMock(); + auto managerMock = MockDistributedFileDaemonManager::GetMock(); + + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(*managerMock, 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) << "TransListenerCoreMockTest-end TransListenerCoreMockTest_PrepareCopySession_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(TransListenerCoreMockTest, TransListenerCoreMockTest_CopyFileFromSoftBus_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TransListenerCoreMockTest-begin TransListenerCoreMockTest_CopyFileFromSoftBus_001"; + + Storage::DistributedFile::HmdfsInfo info; + info.authority = FILE_MANAGER_AUTHORITY; + + string srcUri = "http://translistener.preparecopysession?networkid=AD125AD1CF"; + std::shared_ptr transListener = std::make_shared(); + std::shared_ptr infos = std::make_shared(); + auto unistdMock = UnistdMock::GetMock(); + auto managerMock = MockDistributedFileDaemonManager::GetMock(); + + EXPECT_CALL(*unistdMock, read(testing::_, testing::_, testing::_)).WillRepeatedly(testing::Return(1)); + EXPECT_CALL(*managerMock, 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) << "TransListenerCoreMockTest-end TransListenerCoreMockTest_CopyFileFromSoftBus_001"; +} + +} // 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 new file mode 100644 index 0000000000000000000000000000000000000000..5e6dca23516ed46add8918b2b5dc85bd70ebc938 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/trans_listener_test.cpp @@ -0,0 +1,577 @@ +/* + * 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); + if (fd < 0) { + EXPECT_TRUE(false); + } + 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_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_FALSE(result.empty()); + + 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); + if (fd < 0) { + EXPECT_TRUE(false); + } + 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"; + + std::shared_ptr transListener = std::make_shared(); + 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"; + + std::shared_ptr transListener = std::make_shared(); + 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"; + + 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); + + 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"; + + std::shared_ptr transListener = std::make_shared(); + 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"; + + std::shared_ptr transListener = std::make_shared(); + 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"; + std::shared_ptr transListener = std::make_shared(); + std::shared_ptr infos = std::make_shared(); + 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 diff --git a/interfaces/test/unittest/js/mod_fs/properties/unlink_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/unlink_core_mock_test.cpp index fcd294b5f4beadc8f37eeafb3e1e4120b5a8a737..160a4b63b2b8b42781f878ac7d0190d800b6c4c0 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/unlink_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/unlink_core_mock_test.cpp @@ -15,11 +15,12 @@ #include #include -#include + #include +#include -#include "mock/uv_fs_mock.h" #include "unlink_core.h" +#include "uv_fs_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; diff --git a/interfaces/test/unittest/js/mod_fs/properties/utimes_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/utimes_core_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7d7e60c22b290332f8cbeac98b4b4bd3dce42df --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/utimes_core_mock_test.cpp @@ -0,0 +1,124 @@ +/* + * 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 "utimes_core.h" +#include "uv_fs_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class UtimesCoreMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +}; + +void UtimesCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + uvMock = std::make_shared(); + Uvfs::ins = uvMock; +} + +void UtimesCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + Uvfs::ins = nullptr; + uvMock = nullptr; +} + +void UtimesCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void UtimesCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: UtimesCoreMockTest_DoUtimes_001 + * @tc.desc: Test function of UtimesCore::DoUtimes interface for Failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(UtimesCoreMockTest, UtimesCoreMockTest_DoUtimes_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "UtimesCoreMockTest-begin UtimesCoreMockTest_DoUtimes_001"; + + string path; + double mtime = 1; + + EXPECT_CALL(*uvMock, uv_fs_stat(_, _, _, _)).WillOnce(Return(-1)); + auto res = UtimesCore::DoUtimes(path, mtime); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "UtimesCoreMockTest-end UtimesCoreMockTest_DoUtimes_001"; +} + +/** + * @tc.name: UtimesCoreMockTest_DoUtimes_002 + * @tc.desc: Test function of UtimesCore::DoUtimes interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(UtimesCoreMockTest, UtimesCoreMockTest_DoUtimes_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "UtimesCoreMockTest-begin UtimesCoreMockTest_DoUtimes_002"; + + string path; + double mtime = 1; + + EXPECT_CALL(*uvMock, uv_fs_stat(_, _, _, _)).WillOnce(Return(1)); + EXPECT_CALL(*uvMock, uv_fs_utime(_, _, _, _, _, _)).WillOnce(Return(-1)); + auto res = UtimesCore::DoUtimes(path, mtime); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "UtimesCoreMockTest-end UtimesCoreMockTest_DoUtimes_002"; +} + +/** + * @tc.name: UtimesCoreMockTest_DoUtimes_003 + * @tc.desc: Test function of UtimesCore::DoUtimes interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(UtimesCoreMockTest, UtimesCoreMockTest_DoUtimes_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "UtimesCoreMockTest-begin UtimesCoreMockTest_DoUtimes_003"; + + string path; + double mtime = 1; + + EXPECT_CALL(*uvMock, uv_fs_stat(_, _, _, _)).WillOnce(Return(1)); + EXPECT_CALL(*uvMock, uv_fs_utime(_, _, _, _, _, _)).WillOnce(Return(1)); + auto res = UtimesCore::DoUtimes(path, mtime); + EXPECT_EQ(res.IsSuccess(), true); + + GTEST_LOG_(INFO) << "UtimesCoreMockTest-end UtimesCoreMockTest_DoUtimes_003"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test diff --git a/interfaces/test/unittest/js/mod_fs/properties/utimes_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/utimes_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54ee576ccdf5b0bdb5e025aa8b1f2a3f89cfe7c6 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/utimes_core_test.cpp @@ -0,0 +1,73 @@ +/* + * 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 "utimes_core.h" + +#include + + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class UtimesCoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void UtimesCoreTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void UtimesCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void UtimesCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void UtimesCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: UtimesCoreTest_DoUtimes_001 + * @tc.desc: Test function of UtimesCore::DoUtimes interface for Failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(UtimesCoreTest, UtimesCoreTest_DoUtimes_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "UtimesCoreTest-begin UtimesCoreTest_DoUtimes_001"; + + string path; + double mtime = -1; + auto res = UtimesCore::DoUtimes(path, mtime); + EXPECT_EQ(res.IsSuccess(), false); + + GTEST_LOG_(INFO) << "UtimesCoreTest-end UtimesCoreTest_DoUtimes_001"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test 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 0000000000000000000000000000000000000000..680a2ce3215c1bdd946439c147d1720e643993d1 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/watcher_core_mock_test.cpp @@ -0,0 +1,193 @@ +/* + * 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"; + EventfdMock::EnableMock(); + InotifyMock::EnableMock(); +} + +void WatcherCoreMockTest::TearDownTestCase(void) +{ + EventfdMock::DisableMock(); + InotifyMock::DisableMock(); + 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"; +} + +} // namespace Test +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/xattr_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/xattr_core_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e34ff3bdf009b927d1a853eaeae3f0174f452338 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/xattr_core_mock_test.cpp @@ -0,0 +1,179 @@ +/* + * 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 "system_mock.h" +#include "xattr_core.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class XattrCoreMockTest : public testing::Test { +public: + static filesystem::path tempFilePath; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr sys = nullptr; +}; + +filesystem::path XattrCoreMockTest::tempFilePath; + +void XattrCoreMockTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + tempFilePath = "/data/local/tmp/xattr_test_file.txt"; + ofstream tempfile(tempFilePath); + tempfile << "Test content\n123\n456"; + tempfile.close(); + sys = make_shared(); + System::ins = sys; +} + +void XattrCoreMockTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + filesystem::remove(tempFilePath); + System::ins = nullptr; + sys = nullptr; +} + +void XattrCoreMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void XattrCoreMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: XattrCoreMockTest_DoSetXattr_001 + * @tc.desc: Test function of XattrCore::DoSetXattr interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreMockTest, XattrCoreMockTest_DoSetXattr_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreMockTest-begin XattrCoreMockTest_DoSetXattr_001"; + + string path = tempFilePath.string(); + string key = "test_key"; + string value = "test_value"; + + EXPECT_CALL(*sys, setxattr(_, _, _, _, _)).WillOnce(SetErrnoAndReturn(EIO, -1)); + auto ret = XattrCore::DoSetXattr(path, key, value); + EXPECT_FALSE(ret.IsSuccess()); + + GTEST_LOG_(INFO) << "XattrCoreMockTest-end XattrCoreMockTest_DoSetXattr_001"; +} + +/** + * @tc.name: XattrCoreMockTest_DoSetXattr_002 + * @tc.desc: Test function of XattrCore::DoSetXattr interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreMockTest, XattrCoreMockTest_DoSetXattr_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreMockTest-begin XattrCoreMockTest_DoSetXattr_002"; + + string path = tempFilePath.string(); + string key = "test_key"; + string value = "test_value"; + + EXPECT_CALL(*sys, setxattr(_, _, _, _, _)).WillOnce(Return(0)); + auto ret = XattrCore::DoSetXattr(path, key, value); + EXPECT_TRUE(ret.IsSuccess()); + + GTEST_LOG_(INFO) << "XattrCoreMockTest-end XattrCoreMockTest_DoSetXattr_002"; +} + +/** + * @tc.name: XattrCoreMockTest_DoGetXattr_001 + * @tc.desc: Test function of XattrCore::DoGetXattr interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreMockTest, XattrCoreMockTest_DoGetXattr_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreMockTest-begin XattrCoreMockTest_DoGetXattr_001"; + + string path = tempFilePath.string(); + string key = "test_key"; + + EXPECT_CALL(*sys, getxattr(_, _, _, _)).WillRepeatedly(SetErrnoAndReturn(EIO, -1)); + auto ret = XattrCore::DoGetXattr(path, key); + EXPECT_TRUE(ret.IsSuccess()); + + GTEST_LOG_(INFO) << "XattrCoreMockTest-end XattrCoreMockTest_DoGetXattr_001"; +} + +/** + * @tc.name: XattrCoreMockTest_DoGetXattr_002 + * @tc.desc: Test function of XattrCore::DoGetXattr interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreMockTest, XattrCoreMockTest_DoGetXattr_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreMockTest-begin XattrCoreMockTest_DoGetXattr_002"; + + string path = tempFilePath.string(); + string key = "test_key"; + + EXPECT_CALL(*sys, getxattr(_, _, _, _)).WillOnce(Return(1)).WillOnce(SetErrnoAndReturn(EIO, -1)); + auto ret = XattrCore::DoGetXattr(path, key); + EXPECT_FALSE(ret.IsSuccess()); + + GTEST_LOG_(INFO) << "XattrCoreMockTest-end XattrCoreMockTest_DoGetXattr_002"; +} + +/** + * @tc.name: XattrCoreMockTest_DoGetXattr_003 + * @tc.desc: Test function of XattrCore::DoGetXattr interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreMockTest, XattrCoreMockTest_DoGetXattr_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreMockTest-begin XattrCoreMockTest_DoGetXattr_003"; + + string path = tempFilePath.string(); + string key = "test_key"; + + EXPECT_CALL(*sys, getxattr(_, _, _, _)).WillOnce(Return(1)).WillOnce(Return(1)); + auto ret = XattrCore::DoGetXattr(path, key); + EXPECT_TRUE(ret.IsSuccess()); + + GTEST_LOG_(INFO) << "XattrCoreMockTest-end XattrCoreMockTest_DoGetXattr_003"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/xattr_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/xattr_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..febfd1c1e759677898417e140b8f18ca93cd8bd0 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/xattr_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 +#include + +#include +#include + +#include "xattr_core.h" + +#define MAX_LEN 4096 + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class XattrCoreTest : public testing::Test { +public: + static filesystem::path tempFilePath; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +filesystem::path XattrCoreTest::tempFilePath; + +void XattrCoreTest::SetUpTestCase(void) +{ + tempFilePath = "/data/local/tmp/xattr_test_file.txt"; + ofstream tempfile(tempFilePath); + tempfile << "Test content\n123\n456"; + tempfile.close(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void XattrCoreTest::TearDownTestCase(void) +{ + filesystem::remove(tempFilePath); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void XattrCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void XattrCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: XattrCoreTest_DoSetXattr_001 + * @tc.desc: Test function of XattrCore::DoSetXattr interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreTest, XattrCoreTest_DoSetXattr_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreTest-begin XattrCoreTest_DoSetXattr_001"; + + string path = tempFilePath.string(); + std::string key = "test_key"; + std::string value(MAX_LEN + 1, 'a'); + + auto ret = XattrCore::DoSetXattr(path, key, value); + + EXPECT_FALSE(ret.IsSuccess()); + auto err = ret.GetError(); + int errCode = err.GetErrNo(); + EXPECT_EQ(errCode, 13900020); + auto msg = err.GetErrMsg(); + EXPECT_EQ(msg, "Invalid argument"); + + GTEST_LOG_(INFO) << "XattrCoreTest-end XattrCoreTest_DoSetXattr_001"; +} + +/** + * @tc.name: XattrCoreTest_DoSetXattr_002 + * @tc.desc: Test function of XattrCore::DoSetXattr interface for FAILED. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreTest, XattrCoreTest_DoSetXattr_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreTest-begin XattrCoreTest_DoSetXattr_002"; + + string path = tempFilePath.string(); + std::string key(MAX_LEN + 1, 'a'); + std::string value = "test_value"; + + auto ret = XattrCore::DoSetXattr(path, key, value); + + EXPECT_FALSE(ret.IsSuccess()); + auto err = ret.GetError(); + int errCode = err.GetErrNo(); + EXPECT_EQ(errCode, 13900020); + auto msg = err.GetErrMsg(); + EXPECT_EQ(msg, "Invalid argument"); + + GTEST_LOG_(INFO) << "XattrCoreTest-end XattrCoreTest_DoSetXattr_002"; +} + +/** + * @tc.name: XattrCoreTest_DoGetXattr_001 + * @tc.desc: Test function of XattrCore::DoGetXattr interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(XattrCoreTest, XattrCoreTest_DoGetXattr_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "XattrCoreTest-begin XattrCoreTest_DoGetXattr_001"; + + std::string path = "/data/local/tmp/nonexistent_file"; + string key = "test_key"; + + auto ret = XattrCore::DoGetXattr(path, key); + + ASSERT_TRUE(ret.IsSuccess()); + EXPECT_EQ(ret.GetData().value(), ""); + + GTEST_LOG_(INFO) << "XattrCoreTest-end XattrCoreTest_DoGetXattr_001"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_hash/hash_core_test.cpp b/interfaces/test/unittest/js/mod_hash/hash_core_test.cpp index 069a3230e9d756b9f4a145bbd6e918432ddfa557..0f343b77b050dc6077f111f4780d1656768565f8 100644 --- a/interfaces/test/unittest/js/mod_hash/hash_core_test.cpp +++ b/interfaces/test/unittest/js/mod_hash/hash_core_test.cpp @@ -45,7 +45,6 @@ public: * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(HashCoreTest, DoHashTest_0001, testing::ext::TestSize.Level1) { @@ -66,7 +65,6 @@ HWTEST_F(HashCoreTest, DoHashTest_0001, testing::ext::TestSize.Level1) * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(HashCoreTest, DoHashTest_0002, testing::ext::TestSize.Level1) { @@ -83,7 +81,6 @@ HWTEST_F(HashCoreTest, DoHashTest_0002, testing::ext::TestSize.Level1) * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(HashCoreTest, DoHashTest_0003, testing::ext::TestSize.Level1) { @@ -100,7 +97,6 @@ HWTEST_F(HashCoreTest, DoHashTest_0003, testing::ext::TestSize.Level1) * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(HashCoreTest, DoHashTest_0004, testing::ext::TestSize.Level1) { @@ -117,7 +113,6 @@ HWTEST_F(HashCoreTest, DoHashTest_0004, testing::ext::TestSize.Level1) * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(HashCoreTest, DoHashTest_0005, testing::ext::TestSize.Level1) { diff --git a/interfaces/test/unittest/js/mod_securitylabel/securitylabel_core_test.cpp b/interfaces/test/unittest/js/mod_securitylabel/securitylabel_core_test.cpp index f320af0371ac30c73381a072a2a449b71ebe3a99..e0447335e513853e988d7585e4c8d49d3714b099 100644 --- a/interfaces/test/unittest/js/mod_securitylabel/securitylabel_core_test.cpp +++ b/interfaces/test/unittest/js/mod_securitylabel/securitylabel_core_test.cpp @@ -48,7 +48,6 @@ public: * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(SecurityLabelCoreTest, DoSetSecurityLabel_0001, testing::ext::TestSize.Level1) { @@ -68,7 +67,6 @@ HWTEST_F(SecurityLabelCoreTest, DoSetSecurityLabel_0001, testing::ext::TestSize. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(SecurityLabelCoreTest, DoSetSecurityLabel_0002, testing::ext::TestSize.Level1) { @@ -88,7 +86,6 @@ HWTEST_F(SecurityLabelCoreTest, DoSetSecurityLabel_0002, testing::ext::TestSize. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(SecurityLabelCoreTest, DoSetSecurityLabel_0003, testing::ext::TestSize.Level1) { @@ -105,7 +102,6 @@ HWTEST_F(SecurityLabelCoreTest, DoSetSecurityLabel_0003, testing::ext::TestSize. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(SecurityLabelCoreTest, DoGetSecurityLabel_0001, testing::ext::TestSize.Level1) { @@ -125,7 +121,6 @@ HWTEST_F(SecurityLabelCoreTest, DoGetSecurityLabel_0001, testing::ext::TestSize. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: AR000IGDNF */ HWTEST_F(SecurityLabelCoreTest, DoGetSecurityLabel_0002, testing::ext::TestSize.Level1) { diff --git a/interfaces/test/unittest/js/mod_statvfs/statvfs_core_test.cpp b/interfaces/test/unittest/js/mod_statvfs/statvfs_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..82316d884a2a557cb956332ee3eba59575bc70d0 --- /dev/null +++ b/interfaces/test/unittest/js/mod_statvfs/statvfs_core_test.cpp @@ -0,0 +1,142 @@ +/* + * 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 "statvfs_core.h" + +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class StatvFsCoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void StatvFsCoreTest::SetUpTestCase(void) +{ + GTEST_LOG_(INFO) << "SetUpTestCase"; + int32_t fd = open("/data/test/statvfs.txt", O_CREAT | O_RDWR, 0644); + if (fd <= 0) { + close(fd); + ASSERT_TRUE(false); + } + close(fd); +} + +void StatvFsCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + rmdir("/data/test/statvfs.txt"); +} + +void StatvFsCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void StatvFsCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: StatvFsCoreTest_DoGetFreeSize_001 + * @tc.desc: Test function of DoGetFreeSize interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(StatvFsCoreTest, StatvFsCoreTest_DoGetFreeSize_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StatvFsCoreTest-begin StatvFsCoreTest_DoGetFreeSize_001"; + + struct statvfs diskInfo; + diskInfo.f_bsize = 2; + diskInfo.f_bfree = 1; + + auto result = ModuleStatvfs::StatvfsCore::DoGetFreeSize("/data/test/statvfs.txt"); + EXPECT_EQ(result.IsSuccess(), true); + + GTEST_LOG_(INFO) << "StatvFsCoreTest-end StatvFsCoreTest_DoGetFreeSize_001"; +} + +/** + * @tc.name: StatvFsCoreTest_DoGetFreeSize_002 + * @tc.desc: Test function of DoGetFreeSize interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(StatvFsCoreTest, StatvFsCoreTest_DoGetFreeSize_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StatvFsCoreTest-begin StatvFsCoreTest_DoGetFreeSize_002"; + + auto result = ModuleStatvfs::StatvfsCore::DoGetFreeSize("/test/path"); + EXPECT_EQ(result.IsSuccess(), false); + auto err = result.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900002); + + GTEST_LOG_(INFO) << "StatvFsCoreTest-end StatvFsCoreTest_DoGetFreeSize_002"; +} + +/** + * @tc.name: StatvFsCoreTest_DoGetTotalSize_003 + * @tc.desc: Test function of DoGetTotalSize interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(StatvFsCoreTest, StatvFsCoreTest_DoGetTotalSize_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StatvFsCoreTest-begin StatvFsCoreTest_DoGetTotalSize_003"; + + struct statvfs diskInfo; + diskInfo.f_bsize = 2; + diskInfo.f_blocks = 1; + + auto result = ModuleStatvfs::StatvfsCore::DoGetTotalSize("/data/test/statvfs.txt"); + EXPECT_EQ(result.IsSuccess(), true); + + GTEST_LOG_(INFO) << "StatvFsCoreTest-end StatvFsCoreTest_DoGetTotalSize_003"; +} + +/** + * @tc.name: StatvFsCoreTest_DoGetTotalSize_004 + * @tc.desc: Test function of DoGetTotalSize interface for FALSE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(StatvFsCoreTest, StatvFsCoreTest_DoGetTotalSize_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "StatvFsCoreTest-begin StatvFsCoreTest_DoGetTotalSize_004"; + + auto result = ModuleStatvfs::StatvfsCore::DoGetTotalSize("/test/path"); + EXPECT_EQ(result.IsSuccess(), false); + auto err = result.GetError(); + EXPECT_EQ(err.GetErrNo(), 13900002); + + GTEST_LOG_(INFO) << "StatvFsCoreTest-end StatvFsCoreTest_DoGetTotalSize_004"; +} + +} \ No newline at end of file diff --git a/interfaces/test/unittest/task_signal/BUILD.gn b/interfaces/test/unittest/task_signal/BUILD.gn index 2f9900498e80121911e65beaa44b750ca51d02d5..1789fbbc1259f3a298abadd9ef4779e53eff0cd0 100644 --- a/interfaces/test/unittest/task_signal/BUILD.gn +++ b/interfaces/test/unittest/task_signal/BUILD.gn @@ -3,7 +3,7 @@ # 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 +# 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, @@ -33,7 +33,14 @@ ohos_unittest("task_signal_test") { external_deps = [ "c_utils:utils", + "dfs_service:distributed_file_daemon_kit_inner", + "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", ] + + defines = [ + "ENABLE_DISTRIBUTED_FILE_MOCK", + "private=public", + ] } diff --git a/interfaces/test/unittest/task_signal/task_signal_test.cpp b/interfaces/test/unittest/task_signal/task_signal_test.cpp index fad6cbfc23853deef22d77ffeacff48415fecbca..587dc9c9a97cfa00b5e301c22c9fbac354a7619d 100644 --- a/interfaces/test/unittest/task_signal/task_signal_test.cpp +++ b/interfaces/test/unittest/task_signal/task_signal_test.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 + * 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, @@ -13,146 +13,447 @@ * limitations under the License. */ -#include "task_signal.h" +#include -#include -#include +#include #include -#include +#include "distributed_file_daemon_manager.h" #include "filemgmt_libhilog.h" #include "task_signal_listener.h" +#include "task_signal.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; + } + + 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; + } + + int32_t CancelCopyTask(const std::string &srcUri, const std::string &dstUri) + { + return 0; + } + + int32_t GetDfsSwitchStatus(const std::string &networkId, int32_t &switchStatus) + { + return 0; + } + + int32_t UpdateDfsSwitchStatus(int32_t switchStatus) + { + return 0; + } + + int32_t GetConnectedDeviceList(std::vector &deviceList) + { + 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 { namespace DistributedFS { +namespace ModuleTaskSignal { +namespace Test { using namespace std; using namespace OHOS::DistributedFS::ModuleTaskSignal; -using namespace FileManagement; class TaskSignalTest : public testing::Test { public: - static void SetUpTestCase(void){}; - static void TearDownTestCase(){}; - void SetUp(){}; - void TearDown(){}; - - static std::condition_variable taskListenerCv_; - static std::mutex taskListenerCallbackLock_; - static std::string canceledFilePath_; -}; + static void SetUpTestSuite(void) {} + static void TearDownTestSuite(void) {} -std::condition_variable TaskSignalTest::taskListenerCv_; -std::mutex TaskSignalTest::taskListenerCallbackLock_; -std::string TaskSignalTest::canceledFilePath_; + void SetUp() override + { + taskSignal_ = std::make_unique(); + } -class TaskSignalListenerTestImpl : public TaskSignalListener { -public: - ~TaskSignalListenerTestImpl() = default; - void OnCancel() + void TearDown() override + { + taskSignal_.reset(); + } + + MockDistributedFileDaemonManager &GetMock() { - string path = "aaa"; - TaskSignalTest::canceledFilePath_ = path; - TaskSignalTest::taskListenerCv_.notify_one(); - HILOGI("OnCancel in. path = %{public}s", path.c_str()); + return g_mockDistributedFileDaemonManager; } + +protected: + std::unique_ptr taskSignal_; }; /** - * @tc.name: Task_Signal_Cancel_0000 - * @tc.desc: Test function of Cancel() interface for SUCCESS. + * @tc.name: TaskSignalTest_Cancel_001 + * @tc.desc: Test function of TaskSignal::Cancel interface for SUCCESS when remoteTask_ is false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_Cancel_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_Cancel_001"; + // Prepare test condition + taskSignal_->remoteTask_.store(false); + // Do testing + auto result = taskSignal_->Cancel(); + // Verify results + EXPECT_EQ(result, 0); + EXPECT_TRUE(taskSignal_->needCancel_.load()); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_Cancel_001"; +} + +/** + * @tc.name: TaskSignalTest_Cancel_002 + * @tc.desc: Test function of TaskSignal::Cancel interface for SUCCESS when remoteTask_ is false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_Cancel_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_Cancel_002"; + // Prepare test condition + taskSignal_->remoteTask_.store(true); + taskSignal_->sessionName_ = "TaskSignalTest_Cancel_002"; + // Set mock behaviors + int expectedCode = 0; + EXPECT_CALL(GetMock(), CancelCopyTask(testing::_)).WillOnce(testing::Return(expectedCode)); + // Do testing + auto result = taskSignal_->Cancel(); + // Verify results + EXPECT_EQ(result, 0); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_Cancel_002"; +} + +/** + * @tc.name: TaskSignalTest_Cancel_003 + * @tc.desc: Test function of TaskSignal::Cancel interface for FAILURE when sessionName_ is empty. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_Cancel_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_Cancel_003"; + // Prepare test parameters + taskSignal_->remoteTask_.store(true); + taskSignal_->sessionName_ = ""; + // Do testing + auto result = taskSignal_->Cancel(); + // Verify results + EXPECT_EQ(result, -3); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_Cancel_003"; +} + +/** + * @tc.name: TaskSignalTest_Cancel_004 + * @tc.desc: Test function of TaskSignal::Cancel interface for FAILURE when CancelCopyTask fails. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: NAN */ -HWTEST_F(TaskSignalTest, Task_Signal_Cancel_0000, testing::ext::TestSize.Level1) +HWTEST_F(TaskSignalTest, TaskSignalTest_Cancel_004, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_Cancel_0000"; - auto signal = std::make_shared(); - auto ret = signal->Cancel(); - EXPECT_TRUE(ret == 0); + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_Cancel_004"; + // Prepare test parameters + taskSignal_->remoteTask_.store(true); + taskSignal_->sessionName_ = "TaskSignalTest_Cancel_004"; + // Set mock behaviors + int expectedCode = -1; + EXPECT_CALL(GetMock(), CancelCopyTask(testing::_)).WillOnce(testing::Return(expectedCode)); + // Do testing + auto result = taskSignal_->Cancel(); + // Verify results + EXPECT_EQ(result, expectedCode); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_Cancel_004"; } /** - * @tc.name: Task_Signal_IsCancel_0000 - * @tc.desc: Test function of IsCanceled() interface + * @tc.name: TaskSignalTest_IsCanceled_001 + * @tc.desc: Test function of TaskSignal::IsCanceled interface for case when needCancel_ is true. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: NAN */ -HWTEST_F(TaskSignalTest, Task_Signal_IsCancel_0000, testing::ext::TestSize.Level1) +HWTEST_F(TaskSignalTest, TaskSignalTest_IsCanceled_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_IsCancel_0000"; - auto signal = std::make_shared(); - auto isCanceled = signal->IsCanceled(); - EXPECT_TRUE(!isCanceled); - - auto ret = signal->Cancel(); - EXPECT_TRUE(ret == 0); - isCanceled = signal->IsCanceled(); - EXPECT_TRUE(isCanceled); + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_IsCanceled_001"; + // Prepare test condition + taskSignal_->needCancel_.store(true); + // Do testing + bool result = taskSignal_->IsCanceled(); + // Verify results + EXPECT_TRUE(result); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_IsCanceled_001"; } /** - * @tc.name: Task_Signal_SetTaskSignalListener_0000 - * @tc.desc: Test function of SetTaskSignalListener() interface for SUCCESS. + * @tc.name: TaskSignalTest_IsCanceled_002 + * @tc.desc: Test function of TaskSignal::IsCanceled interface for case when remoteTask_ is true. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: NAN */ -HWTEST_F(TaskSignalTest, Task_Signal_SetTaskSignalListener_0000, testing::ext::TestSize.Level1) +HWTEST_F(TaskSignalTest, TaskSignalTest_IsCanceled_002, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_SetTaskSignalListener_0000"; - std::unique_lock lock(TaskSignalTest::taskListenerCallbackLock_); - auto signal = std::make_shared(); - auto listener = std::make_shared(); - signal->SetTaskSignalListener(listener.get()); - std::string filePath = "aaa"; - listener->OnCancel(); - signal->CheckCancelIfNeed(filePath); - EXPECT_EQ(TaskSignalTest::canceledFilePath_, filePath); + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_IsCanceled_002"; + // Prepare test condition + taskSignal_->remoteTask_.store(true); + // Do testing + bool result = taskSignal_->IsCanceled(); + // Verify results + EXPECT_TRUE(result); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_IsCanceled_002"; } /** - * @tc.name: Task_Signal_MarkRemoteTask_0000 - * @tc.desc: Test function of MarkRemoteTask() and SetFileInfoOfRemoteTask() interface for SUCCESS. + * @tc.name: TaskSignalTest_IsCanceled_003 + * @tc.desc: Test function of TaskSignal::IsCanceled interface for case when both needCancel_ and remoteTask_ are false. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: NAN */ -HWTEST_F(TaskSignalTest, Task_Signal_MarkRemoteTask_0000, testing::ext::TestSize.Level1) +HWTEST_F(TaskSignalTest, TaskSignalTest_IsCanceled_003, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_MarkRemoteTask_0000"; - auto signal = std::make_shared(); - signal->MarkRemoteTask(); - std::string sessionName = "DistributedDevice0"; - std::string filePath = "aaa"; - signal->SetFileInfoOfRemoteTask(sessionName, filePath); - auto ret = signal->Cancel(); - EXPECT_EQ(ret, 4); + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_IsCanceled_003"; + // Prepare test condition + taskSignal_->needCancel_.store(false); + taskSignal_->remoteTask_.store(false); + // Do testing + bool result = taskSignal_->IsCanceled(); + // Verify results + EXPECT_FALSE(result); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_IsCanceled_003"; } /** - * @tc.name: Task_Signal_MarkDfsTask_0000 - * @tc.desc: Test function of MarkDfsTask() interface for SUCCESS. + * @tc.name: TaskSignalTest_SetTaskSignalListener_001 + * @tc.desc: Test function of TaskSignal::SetTaskSignalListener interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 - * @tc.require: NAN */ -HWTEST_F(TaskSignalTest, Task_Signal_MarkDfsTask_0000, testing::ext::TestSize.Level1) +HWTEST_F(TaskSignalTest, TaskSignalTest_SetTaskSignalListener_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "TaskSignalTest-begin Task_Signal_MarkDfsTask_0000"; - auto signal = std::make_shared(); - signal->MarkDfsTask(); - std::string localUri = "/data/test/test.txt"; - std::string dstUri = "/data/test/test.txt"; - signal->SetCopyTaskUri(localUri, dstUri); - auto ret = signal->Cancel(); - EXPECT_EQ(ret, 0); + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_SetTaskSignalListener_001"; + // Prepare test parameters + MockTaskSignalListener mockListener; + // Do testing + taskSignal_->SetTaskSignalListener(&mockListener); + // Verify results + EXPECT_EQ(taskSignal_->signalListener_, &mockListener); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_SetTaskSignalListener_001"; } + +/** + * @tc.name: TaskSignalTest_SetTaskSignalListener_002 + * @tc.desc: Test function of TaskSignal::SetTaskSignalListener interface for FAILURE. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_SetTaskSignalListener_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_SetTaskSignalListener_002"; + // Prepare test parameters + MockTaskSignalListener expectedListener; + // Prepre test condition + MockTaskSignalListener mockListener; + taskSignal_->signalListener_ = &mockListener; + // Do testing + taskSignal_->SetTaskSignalListener(&expectedListener); + // Verify results + EXPECT_EQ(taskSignal_->signalListener_, &mockListener); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_SetTaskSignalListener_002"; +} + +/** + * @tc.name: TaskSignalTest_OnCancel_001 + * @tc.desc: Test function of TaskSignal::OnCancel interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_OnCancel_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_OnCancel_001"; + // Set mock behaviors + MockTaskSignalListener mockListener; + taskSignal_->signalListener_ = &mockListener; + EXPECT_CALL(mockListener, OnCancel()).Times(1); + // Do testing + taskSignal_->OnCancel(); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_OnCancel_001"; +} + +/** + * @tc.name: TaskSignalTest_CheckCancelIfNeed_001 + * @tc.desc: Test function of TaskSignal::CheckCancelIfNeed interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_CheckCancelIfNeed_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_CheckCancelIfNeed_001"; + // Set mock behaviors + taskSignal_->needCancel_.store(true); + MockTaskSignalListener mockListener; + taskSignal_->signalListener_ = &mockListener; + EXPECT_CALL(mockListener, OnCancel()).Times(1); + // Do testing + bool result = taskSignal_->CheckCancelIfNeed("TaskSignalTest_CheckCancelIfNeed_001"); + // Verify results + EXPECT_TRUE(result); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_CheckCancelIfNeed_001"; +} + +/** + * @tc.name: TaskSignalTest_CheckCancelIfNeed_002 + * @tc.desc: Test function of TaskSignal::CheckCancelIfNeed interface for FAILURE when needCancel_ is false. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_CheckCancelIfNeed_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_CheckCancelIfNeed_002"; + // Prepare test condition + taskSignal_->needCancel_.store(false); + // Do testing + bool result = taskSignal_->CheckCancelIfNeed("TaskSignalTest_CheckCancelIfNeed_002"); + // Verify results + EXPECT_FALSE(result); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_CheckCancelIfNeed_002"; +} + +/** + * @tc.name: TaskSignalTest_MarkRemoteTask_001 + * @tc.desc: Test function of TaskSignal::MarkRemoteTask interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_MarkRemoteTask_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_MarkRemoteTask_001"; + // Do testing + taskSignal_->MarkRemoteTask(); + // Verify results + EXPECT_TRUE(taskSignal_->remoteTask_.load()); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_MarkRemoteTask_001"; +} + +/** + * @tc.name: TaskSignalTest_SetFileInfoOfRemoteTask_001 + * @tc.desc: Test function of TaskSignal::SetFileInfoOfRemoteTask interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(TaskSignalTest, TaskSignalTest_SetFileInfoOfRemoteTask_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "TaskSignalTest-begin TaskSignalTest_SetFileInfoOfRemoteTask_001"; + // Prepare test parameters + std::string sessionName = "testSession"; + std::string filePath = "testFilePath"; + // Do testing + taskSignal_->SetFileInfoOfRemoteTask(sessionName, filePath); + // Verify results + EXPECT_EQ(taskSignal_->sessionName_, sessionName); + EXPECT_EQ(taskSignal_->filePath_, filePath); + GTEST_LOG_(INFO) << "TaskSignalTest-end TaskSignalTest_SetFileInfoOfRemoteTask_001"; +} + +} // namespace Test +} // namespace ModuleTaskSignal } // namespace DistributedFS } // namespace OHOS \ No newline at end of file