diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 9a3e2915ec3f109a57fc3638b5b85cec8f2c784f..928de28e382890009f545c4ee29cf27b1cefabd4 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -19,6 +19,7 @@ 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", @@ -28,6 +29,7 @@ group("file_api_unittest") { "js:napi_file_fs_test", "remote_uri:remote_uri_test", "task_signal:task_signal_test", + "napi_js:napi_file_fs_properties_test", ] if (file_api_feature_hyperaio) { deps += [ "hyperaio:hyperaio_test" ] diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index f0326f9b29f813ff9e919c01171dfd0729bb20a2..ef45eb3ad7a50e77db4fed95865843ed01b137cc 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -324,27 +324,66 @@ ohos_unittest("napi_file_fs_test") { module_out_path = "file_api/file_api" - include_dirs = [ "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher" ] + include_dirs = [ + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_randomaccessfile", + "${file_api_path}/interfaces/kits/js/src/common", + "${file_api_path}/interfaces/kits/js/src/common/file_helper", + "${file_api_path}/interfaces/kits/js/src/mod_fs", + "${utils_path}/common/include", + "mod_fs/properties/mock", + "mod_fs/class_randomaccessfile/mock", + ] sources = [ "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp", + "${file_api_path}/interfaces/kits/js/src/common/file_helper/fd_guard.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/common_func.cpp", "mod_fs/class_watcher/watcher_entity_test.cpp", + "mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp", + "mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp", + "mod_fs/properties/mock/uv_fs_mock.cpp", ] deps = [ "${file_api_path}/interfaces/kits/js:fs", + "${file_api_path}/interfaces/kits/native:remote_uri_native", "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", "${utils_path}/filemgmt_libn:filemgmt_libn", ] external_deps = [ + "ability_base:zuri", "c_utils:utils", + "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", "libuv:uv", "napi:ace_napi", + "app_file_service:fileuri_native", + "ipc:ipc_core", + "samgr:samgr_proxy", ] + include_dirs += [ "${file_api_path}/interfaces/kits/rust/include" ] + + external_deps += [ + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "access_token:libtokenid_sdk", + "app_file_service:fileuri_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "data_share:datashare_common", + "data_share:datashare_consumer", + "dfs_service:distributed_file_daemon_kit_inner", + "dfs_service:libdistributedfileutils", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + defines = [ "private=public" ] use_exceptions = true diff --git a/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aef023ef0338602315628df8234036530eafe67a --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp @@ -0,0 +1,159 @@ +/* + * 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 "randomaccessfile_n_exporter_mock.h" + #include "n_class.h" + + #include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptr + RandomAccessFileNExporterMock::randomAccessFileNExporterMock = nullptr; +thread_local bool RandomAccessFileNExporterMock::mockable = false; + +std::shared_ptr RandomAccessFileNExporterMock::GetMock() +{ + if (randomAccessFileNExporterMock == nullptr) { + randomAccessFileNExporterMock = std::make_shared(); + } + return randomAccessFileNExporterMock; +} + +void RandomAccessFileNExporterMock::EnableMock() +{ + mockable = true; +} + +void RandomAccessFileNExporterMock::DisableMock() +{ + randomAccessFileNExporterMock = nullptr; + mockable = false; +} + +bool RandomAccessFileNExporterMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +bool NFuncArg::InitArgs(std::function argcChecker) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->InitArgs(argcChecker); + } + + static bool (*realInitArgs)(std::function) = []() { + auto func = (bool(*)(std::function))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argcChecker); +} + +napi_value NFuncArg::GetThisVar() const +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->GetThisVar(); + } + + static napi_value (*realGetThisVar)() = []() { + auto func = (napi_value(*)())dlsym(RTLD_NEXT, "GetThisVar"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetThisVar: " << dlerror(); + } + return func; + }(); + + if (!realGetThisVar) { + return nullptr; + } + + return realGetThisVar(); +} + +napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->napi_unwrap(env, js_object, result); + } + + static napi_status (*realNapi)(napi_env, napi_value, void **) = []() { + auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_unwrap"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real napi_unwrap: " << dlerror(); + } + return func; + }(); + + if (!realNapi) { + return napi_ok; + } + + return realNapi(env, js_object, result); +} + +napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->napi_remove_wrap(env, js_object, result); + } + + static napi_status (*realNapi)(napi_env, napi_value, void **) = []() { + auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_remove_wrap"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real napi_remove_wrap: " << dlerror(); + } + return func; + }(); + + if (!realNapi) { + return napi_ok; + } + + return realNapi(env, js_object, result); +} + +NVal NVal::CreateUndefined(napi_env env) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->CreateUndefined(env); + } + + static NVal (*realCreateUndefined)(napi_env) = []() { + auto func = (NVal(*)(napi_env))dlsym(RTLD_NEXT, "CreateUndefined"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real CreateUndefined: " << dlerror(); + } + return func; + }(); + + if (!realCreateUndefined) { + return {nullptr, nullptr}; + } + + return realCreateUndefined(env); +} \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..17df0d8a8b909c8710eda71449b04b09e626866b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h @@ -0,0 +1,65 @@ +/* + * 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_RANDOMACCESSFILENEXPORTER_MOCK_H +#define INTERFACES_TEST_UNITTEST_RANDOMACCESSFILENEXPORTER_MOCK_H + +#include "filemgmt_libn.h" +#include "randomaccessfile_n_exporter.h" +#include "randomaccessfile_entity.h" + +#include +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; + +class IRandomAccessFileNExporterMock { +public: + virtual ~IRandomAccessFileNExporterMock() = default; + virtual bool InitArgs(std::function argcChecker) = 0; + virtual napi_value GetThisVar() = 0; + virtual napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) = 0; + virtual napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result) = 0; + virtual RandomAccessFileEntity* RemoveEntityOfFinal(napi_env env, napi_value napi_value) = 0; + virtual NVal CreateUndefined(napi_env env) = 0; +}; + +class RandomAccessFileNExporterMock : public IRandomAccessFileNExporterMock { +public: +MOCK_METHOD(bool, InitArgs, (std::function), (override)); +MOCK_METHOD(napi_value, GetThisVar, (), (override)); +MOCK_METHOD(napi_status, napi_unwrap, (napi_env, napi_value, void **), (override)); +MOCK_METHOD(napi_status, napi_remove_wrap, (napi_env, napi_value, void **), (override)); +MOCK_METHOD(RandomAccessFileEntity*, RemoveEntityOfFinal, (napi_env, napi_value), (override)); +MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr randomAccessFileNExporterMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_RANDOMACCESSFILENEXPORTER_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..512a97d0b8d155bf93bf1368cf41290ccb0d153c --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp @@ -0,0 +1,103 @@ +/* + * 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 "randomaccessfile_n_exporter.h" +#include "randomaccessfile_entity.h" +#include "uv_fs_mock.h" +#include "randomaccessfile_n_exporter_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class RandomAccessFileNExporterMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +protected: + unique_ptr rafEntity; +}; + +void RandomAccessFileNExporterMockTest::SetUpTestCase(void) +{ + uvMock = make_shared(); + Uvfs::ins = uvMock; + RandomAccessFileNExporterMock::EnableMock(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void RandomAccessFileNExporterMockTest::TearDownTestCase(void) +{ + Uvfs::ins = nullptr; + uvMock = nullptr; + RandomAccessFileNExporterMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void RandomAccessFileNExporterMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + rafEntity = make_unique(); + const int fdValue = 3; + const bool isClosed = false; + rafEntity->fd = make_unique(fdValue, isClosed); + rafEntity->filePointer = 0; + +} + +void RandomAccessFileNExporterMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: RandomAccessFileNExporterMockTest_CloseSync_001 + * @tc.desc: Test function of CloseSync() interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + +*/ +HWTEST_F(RandomAccessFileNExporterMockTest, RandomAccessFileNExporterMockTest_CloseSync_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "RandomAccessFileNExporterMockTest-begin RandomAccessFileNExporterMockTest_CloseSync_001"; + napi_env env = reinterpret_cast(0x1000); + napi_callback_info mInfo = reinterpret_cast(0x1122); + napi_value nv = reinterpret_cast(0x1200); + NVal mockNval = {env, nv}; + + auto rafNEMock = RandomAccessFileNExporterMock::GetMock(); + EXPECT_CALL(*rafNEMock, InitArgs(_)).WillOnce(Return(true)); + EXPECT_CALL(*rafNEMock, GetThisVar()).WillOnce(Return(nv)).WillOnce(Return(nv)); + EXPECT_CALL(*rafNEMock, napi_unwrap(_, _, _)) + .WillOnce(DoAll(SetArgPointee<2>(static_cast(rafEntity.get())), Return(napi_ok))); + EXPECT_CALL(*uvMock, uv_fs_close(_, _, _, _)).WillOnce(Return(0)); + EXPECT_CALL(*rafNEMock, napi_remove_wrap(_, _, _)) + .WillOnce(DoAll(SetArgPointee<2>(static_cast(rafEntity.get())), Return(napi_ok))); + EXPECT_CALL(*rafNEMock, CreateUndefined(_)).WillOnce(Return(mockNval)); + + auto res = RandomAccessFileNExporter::CloseSync(env, mInfo); + EXPECT_NE(res, nullptr); + + GTEST_LOG_(INFO) << "RandomAccessFileNExporterMockTest-end RandomAccessFileNExporterMockTest_CloseSync_001"; +} + +} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/BUILD.gn b/interfaces/test/unittest/napi_js/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..bf039cf3e8e29d1889a2cde5de2c08c4f1cbca48 --- /dev/null +++ b/interfaces/test/unittest/napi_js/BUILD.gn @@ -0,0 +1,88 @@ +# Copyright (C) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/filemanagement/file_api/file_api.gni") + +ohos_unittest("napi_file_fs_properties_test") { + branch_protector_ret = "pac_ret" + testonly = true + + module_out_path = "file_api/file_api" + + include_dirs = [ + "${file_api_path}/interfaces/kits/js/src/common", + "${file_api_path}/interfaces/kits/js/src/common/file_helper", + "${file_api_path}/interfaces/kits/js/src/mod_fs", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", + "${file_api_path}/interfaces/kits/native/task_signal", + "${utils_path}/common/include", + "mock", + "mod_fs/mock", + ] + + sources = [ + "${file_api_path}/interfaces/kits/js/src/common/file_helper/fd_guard.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/common_func.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp", + "mock/fdatasync_mock.cpp", + "fdatasync_mock_test.cpp", + "mock/prop_n_exporter_mock.cpp", + "prop_n_exporter_mock_test.cpp", + "mod_fs/mock/libn_mock.cpp", + "mod_fs/mock/uv_fs_mock.cpp", + ] + + deps = [ + "${file_api_path}/interfaces/kits/js:fs", + "${file_api_path}/interfaces/kits/native:remote_uri_native", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + "${utils_path}/filemgmt_libn:filemgmt_libn", + ] + + external_deps = [ + "ability_base:zuri", + "c_utils:utils", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "libuv:uv", + "napi:ace_napi", + "app_file_service:fileuri_native", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + + include_dirs += [ "${file_api_path}/interfaces/kits/rust/include" ] + + external_deps += [ + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "access_token:libtokenid_sdk", + "app_file_service:fileuri_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "data_share:datashare_common", + "data_share:datashare_consumer", + "dfs_service:distributed_file_daemon_kit_inner", + "dfs_service:libdistributedfileutils", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + + defines = [ "private=public" ] + + use_exceptions = true +} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ef6eefff6b3bc483a22fe88159d13b5c82dddb7 --- /dev/null +++ b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "fdatasync.h" +#include "uv_fs_mock.h" +#include "fdatasync_mock.h" +#include "libn_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class FdatasyncMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +protected: + +}; + +void FdatasyncMockTest::SetUpTestCase(void) +{ + uvMock = make_shared(); + FdatasyncMock::EnableMock(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FdatasyncMockTest::TearDownTestCase(void) +{ + uvMock = nullptr; + FdatasyncMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FdatasyncMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + +} + +void FdatasyncMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FdatasyncMockTest_Sync_001 + * @tc.desc: Test function of Sync() interface for uv_fs_fdatasync failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + +*/ +HWTEST_F(FdatasyncMockTest, FdatasyncMockTest_Sync_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FdatasyncMockTest-begin FdatasyncMockTest_Sync_001"; + napi_env env = reinterpret_cast(0x1000); + napi_value nv = reinterpret_cast(0x1200); + napi_callback_info mInfo = reinterpret_cast(0x1122); + tuple tp = {true, 1}; + + auto pMock = LibnMock::GetMock(); + EXPECT_CALL(*pMock, InitArgs(A())).WillOnce(Return(true)); + EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); + EXPECT_CALL(*pMock, ToInt32()).WillOnce(Return(tp)); + EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(-1)); + EXPECT_CALL(*pMock, ThrowErr(_)); + + auto res = Fdatasync::Sync(env, mInfo); + EXPECT_EQ(res, nullptr); + + GTEST_LOG_(INFO) << "FdatasyncMockTest-end FdatasyncMockTest_Sync_001"; +} + +} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21fd2e8062a7b0927f46ac926a8d5d0f673a90c4 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp @@ -0,0 +1,74 @@ +/* + * 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_mock.h" + #include "n_class.h" + + #include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptrFdatasyncMock::fdatasyncMock = nullptr; +thread_local bool FdatasyncMock::mockable = false; + +std::shared_ptr FdatasyncMock::GetMock() +{ + if (fdatasyncMock == nullptr) { + fdatasyncMock = std::make_shared(); + } + return fdatasyncMock; +} + +void FdatasyncMock::EnableMock() +{ + mockable = true; +} + +void FdatasyncMock::DisableMock() +{ + fdatasyncMock = nullptr; + mockable = false; +} + +bool FdatasyncMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +NVal NVal::CreateUndefined(napi_env env) +{ + if (FdatasyncMock::IsMockable()) { + return FdatasyncMock::GetMock()->CreateUndefined(env); + } + + static NVal (*realCreateUndefined)(napi_env) = []() { + auto func = (NVal(*)(napi_env))dlsym(RTLD_NEXT, "CreateUndefined"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real CreateUndefined: " << dlerror(); + } + return func; + }(); + + if (!realCreateUndefined) { + return {nullptr, nullptr}; + } + + return realCreateUndefined(env); +} diff --git a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..87a355df36ac98f27d5ac56677931a73cb9987a0 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h @@ -0,0 +1,55 @@ +/* + * 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_FDATASYNC_MOCK_H +#define INTERFACES_TEST_UNITTEST_FDATASYNC_MOCK_H + +#include "filemgmt_libn.h" +#include "fdatasync.h" + +#include +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; +using std::tuple; + +class IFdatasyncMock { +public: + virtual ~IFdatasyncMock() = default; + virtual NVal CreateUndefined(napi_env env) = 0; +}; + +class FdatasyncMock : public IFdatasyncMock { +public: +MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr fdatasyncMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_FDATASYNC_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21919baea7131a6f030689ad3e468c431d930101 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp @@ -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. + */ + + #include "prop_n_exporter_mock.h" + #include "n_class.h" + + #include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptrPropNExporterMock::pPropNExporterMock = nullptr; +thread_local bool PropNExporterMock::mockable = false; + +std::shared_ptr PropNExporterMock::GetMock() +{ + if (pPropNExporterMock == nullptr) { + pPropNExporterMock = std::make_shared(); + } + return pPropNExporterMock; +} + +void PropNExporterMock::EnableMock() +{ + mockable = true; +} + +void PropNExporterMock::DisableMock() +{ + pPropNExporterMock = nullptr; + mockable = false; +} + +bool PropNExporterMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +using namespace OHOS::FileManagement::ModuleFileIO::Test; + diff --git a/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..0f8f130eb32aa9df4fab28e45a2ab92a17fdbea5 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h @@ -0,0 +1,65 @@ +/* + * 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_PROPNEXPORTER_MOCK_H +#define INTERFACES_TEST_UNITTEST_PROPNEXPORTER_MOCK_H + +#include "filemgmt_libn.h" +#include "prop_n_exporter.h" + +#include +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; +using std::tuple; + +class IPropNExporterMock { +public: + virtual ~IPropNExporterMock() = default; + virtual bool InitArgs(std::function argcChecker) = 0; + virtual napi_value GetThisVar() = 0; + virtual NVal CreateUndefined(napi_env env) = 0; + virtual napi_value GetArg(size_t argPos) = 0; + virtual tuple ToInt32() = 0; + virtual void ThrowErr(napi_env env, std::string errMsg) = 0; +}; + +class PropNExporterMock : public IPropNExporterMock { +public: +MOCK_METHOD(bool, InitArgs, (std::function), (override)); +MOCK_METHOD(napi_value, GetThisVar, (), (override)); +MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); +MOCK_METHOD(napi_value, GetArg, (size_t), (override)); +MOCK_METHOD((tuple), ToInt32, (), (override)); +MOCK_METHOD(void, ThrowErr, (napi_env, std::string), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr pPropNExporterMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_PROPNEXPORTER_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2f8dd42c51638889947d2347c05985c9e40d418a --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp @@ -0,0 +1,498 @@ +/* + * 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 "libn_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptr LibnMock::libnMock = nullptr; +thread_local bool LibnMock::mockable = false; + +std::shared_ptr LibnMock::GetMock() +{ + if (libnMock == nullptr) { + libnMock = std::make_shared(); + } + return libnMock; +} + +void LibnMock::EnableMock() +{ + mockable = true; +} + +void LibnMock::DisableMock() +{ + libnMock = nullptr; + mockable = false; +} + +bool LibnMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +#ifdef __cplusplus +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +extern "C" { +napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->napi_unwrap(env, js_object, result); + } + + static napi_status (*realNapi)(napi_env, napi_value, void **) = []() { + auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_unwrap"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real napi_unwrap: " << dlerror(); + } + return func; + }(); + + if (!realNapi) { + return napi_ok; + } + + return realNapi(env, js_object, result); +} + +} // extern "C" + +bool NFuncArg::InitArgs(std::function argcChecker) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->InitArgs(argcChecker); + } + + static bool (*realInitArgs)(std::function) = []() { + auto func = (bool (*)(std::function))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argcChecker); +} + +bool NFuncArg::InitArgs(size_t argc) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->InitArgs(argc); + } + + static bool (*realInitArgs)(size_t) = []() { + auto func = (bool (*)(size_t))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argc); +} + +bool NFuncArg::InitArgs(size_t minArgc, size_t maxArgc) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->InitArgs(minArgc, maxArgc); + } + + static bool (*realInitArgs)(size_t, size_t) = []() { + auto func = (bool (*)(size_t, size_t))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(minArgc, maxArgc); +} + +size_t NFuncArg::GetArgc() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->GetArgc(); + } + + static size_t (*realGetArgc)() = []() { + auto func = (size_t (*)())dlsym(RTLD_NEXT, "GetArgc"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetArgc: " << dlerror(); + } + return func; + }(); + + if (!realGetArgc) { + return -1; + } + + return realGetArgc(); +} + +napi_value NFuncArg::GetThisVar() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->GetThisVar(); + } + + static napi_value (*realGetThisVar)() = []() { + auto func = (napi_value (*)())dlsym(RTLD_NEXT, "GetThisVar"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetThisVar: " << dlerror(); + } + return func; + }(); + + if (!realGetThisVar) { + return nullptr; + } + + return realGetThisVar(); +} + +napi_value NFuncArg::GetArg(size_t argPos) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->GetArg(argPos); + } + + static napi_value (*realGetArg)(size_t) = []() { + auto func = (napi_value (*)(size_t))dlsym(RTLD_NEXT, "GetArg"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetArg: " << dlerror(); + } + return func; + }(); + + if (!realGetArg) { + return nullptr; + } + + return realGetArg(argPos); +} + +void NError::ThrowErr(napi_env env) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErr(env); + } + + static void (*realThrowErr)(napi_env) = []() { + auto func = (void (*)(napi_env))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env); +} + +void NError::ThrowErr(napi_env env, int errCode) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErr(env, errCode); + } + + static void (*realThrowErr)(napi_env, int) = []() { + auto func = (void (*)(napi_env, int))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errCode); +} + +void NError::ThrowErr(napi_env env, std::string errMsg) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErr(env, errMsg); + } + + static void (*realThrowErr)(napi_env, std::string) = []() { + auto func = (void (*)(napi_env, std::string))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errMsg); +} + +void NError::ThrowErrAddData(napi_env env, int errCode, napi_value data) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErrAddData(env, errCode, data); + } + + static void (*realThrowErr)(napi_env, int, napi_value) = []() { + auto func = (void (*)(napi_env, int, napi_value))dlsym(RTLD_NEXT, "ThrowErrAddData"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErrAddData: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errCode, data); +} + +std::tuple, size_t> NVal::ToUTF8String() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToUTF8String(); + } + + static std::tuple, size_t> (*realToUTF8String)() = []() { + auto func = (std::tuple, size_t> (*)())dlsym(RTLD_NEXT, "ToUTF8String"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToUTF8String: " << dlerror(); + } + return func; + }(); + + if (!realToUTF8String) { + return { false, nullptr, -1 }; + } + + return realToUTF8String(); +} + +std::tuple, size_t> NVal::ToUTF8String(std::string defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToUTF8String(defaultValue); + } + + static std::tuple, size_t> (*realToUTF8String)(std::string) = []() { + auto func = (std::tuple, size_t> (*)(std::string))dlsym(RTLD_NEXT, "ToUTF8String"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToUTF8String: " << dlerror(); + } + return func; + }(); + + if (!realToUTF8String) { + return { false, nullptr, -1 }; + } + + return realToUTF8String(defaultValue); +} + +std::tuple NVal::ToBool() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToBool(); + } + + static std::tuple (*realToBool)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToBool"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToBool: " << dlerror(); + } + return func; + }(); + + if (!realToBool) { + return { false, false }; + } + + return realToBool(); +} + +std::tuple NVal::ToBool(bool defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToBool(defaultValue); + } + + static std::tuple (*realToBool)(bool) = []() { + auto func = (std::tuple (*)(bool))dlsym(RTLD_NEXT, "ToBool"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToBool: " << dlerror(); + } + return func; + }(); + + if (!realToBool) { + return { false, false }; + } + + return realToBool(defaultValue); +} + +std::tuple NVal::ToInt32() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt32(); + } + + static std::tuple (*realToInt32)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToInt32"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt32: " << dlerror(); + } + return func; + }(); + + if (!realToInt32) { + return { false, 0 }; + } + + return realToInt32(); +} + +std::tuple NVal::ToInt32(int32_t defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt32(defaultValue); + } + + static std::tuple (*realToInt32)(int32_t) = []() { + auto func = (std::tuple (*)(int32_t))dlsym(RTLD_NEXT, "ToInt32"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt32: " << dlerror(); + } + return func; + }(); + + if (!realToInt32) { + return { false, 0 }; + } + + return realToInt32(defaultValue); +} + +std::tuple NVal::ToInt64() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt64(); + } + + static std::tuple (*realToInt64)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToInt64"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt64: " << dlerror(); + } + return func; + }(); + + if (!realToInt64) { + return { false, 0 }; + } + + return realToInt64(); +} + +std::tuple NVal::ToInt64(int64_t defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt64(defaultValue); + } + + static std::tuple (*realToInt64)(int64_t) = []() { + auto func = (std::tuple (*)(int64_t))dlsym(RTLD_NEXT, "ToInt64"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt64: " << dlerror(); + } + return func; + }(); + + if (!realToInt64) { + return { false, 0 }; + } + + return realToInt64(defaultValue); +} + +std::tuple NVal::ToDouble() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToDouble(); + } + + static std::tuple (*realToDouble)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToDouble"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToDouble: " << dlerror(); + } + return func; + }(); + + if (!realToDouble) { + return { false, 0 }; + } + + return realToDouble(); +} + +std::tuple, size_t> NVal::ToUTF8StringPath() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToUTF8StringPath(); + } + + static std::tuple, size_t> (*realToUTF8StringPath)() = []() { + auto func = (std::tuple, size_t> (*)())dlsym(RTLD_NEXT, "ToUTF8StringPath"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToUTF8StringPath: " << dlerror(); + } + return func; + }(); + + if (!realToUTF8StringPath) { + return { false, nullptr, -1 }; + } + + return realToUTF8StringPath(); +} +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..082a27943ee78ab388629093b1d6ddcf0fd36b78 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h @@ -0,0 +1,103 @@ +/* + * 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_NAPI_JS_MOD_FS_MOCK_NAPI_MOCK_H +#define INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_MOCK_NAPI_MOCK_H + +#include "n_napi.h" +#include "filemgmt_libn.h" + +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; + +class ILibnMock { +public: + virtual ~ILibnMock() = default; + + // n_func_arg + virtual bool InitArgs(std::function argcChecker) = 0; + virtual bool InitArgs(size_t argc) = 0; + virtual bool InitArgs(size_t minArgc, size_t maxArgc) = 0; + virtual size_t GetArgc() = 0; + virtual napi_value GetArg(size_t argPos) = 0; + virtual napi_value GetThisVar() = 0; + + // n_class GetEntityOf + virtual napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) = 0; + + // n_error + virtual void ThrowErr(napi_env env) = 0; + virtual void ThrowErr(napi_env env, int errCode) = 0; + virtual void ThrowErr(napi_env env, std::string errMsg) = 0; + virtual void ThrowErrAddData(napi_env env, int errCode, napi_value data) = 0; + + // n_val + virtual std::tuple, size_t> ToUTF8String() = 0; + virtual std::tuple, size_t> ToUTF8StringPath() = 0; + virtual std::tuple, size_t> ToUTF8String(std::string defaultValue) = 0; + virtual std::tuple ToBool() = 0; + virtual std::tuple ToBool(bool defaultValue) = 0; + virtual std::tuple ToInt32() = 0; + virtual std::tuple ToInt32(int32_t defaultValue) = 0; + virtual std::tuple ToInt64() = 0; + virtual std::tuple ToInt64(int64_t defaultValue) = 0; + virtual std::tuple ToDouble() = 0; +}; + +class LibnMock : public ILibnMock { +public: + MOCK_METHOD(bool, InitArgs, (std::function), (override)); + MOCK_METHOD(bool, InitArgs, (size_t), (override)); + MOCK_METHOD(bool, InitArgs, (size_t, size_t), (override)); + MOCK_METHOD(size_t, GetArgc, (), (override)); + MOCK_METHOD(napi_value, GetArg, (size_t), (override)); + MOCK_METHOD(napi_value, GetThisVar, (), (override)); + + MOCK_METHOD(napi_status, napi_unwrap, (napi_env, napi_value, void **), (override)); + + MOCK_METHOD(void, ThrowErr, (napi_env), (override)); + MOCK_METHOD(void, ThrowErr, (napi_env, int), (override)); + MOCK_METHOD(void, ThrowErr, (napi_env, std::string), (override)); + MOCK_METHOD(void, ThrowErrAddData, (napi_env, int, napi_value), (override)); + + MOCK_METHOD((std::tuple, size_t>), ToUTF8String, (), (override)); + MOCK_METHOD((std::tuple, size_t>), ToUTF8StringPath, (), (override)); + MOCK_METHOD((std::tuple, size_t>), ToUTF8String, (std::string), (override)); + MOCK_METHOD((std::tuple), ToBool, (), (override)); + MOCK_METHOD((std::tuple), ToBool, (bool), (override)); + MOCK_METHOD((std::tuple), ToInt32, (), (override)); + MOCK_METHOD((std::tuple), ToInt32, (int32_t), (override)); + MOCK_METHOD((std::tuple), ToInt64, (), (override)); + MOCK_METHOD((std::tuple), ToInt64, (int64_t), (override)); + MOCK_METHOD((std::tuple), ToDouble, (), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr libnMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_MOCK_NAPI_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e8f9c8eeaa0563cc2c4ae104abc2d93c80d5ec2 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp @@ -0,0 +1,118 @@ +/* + * 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 "uv_fs_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptr UvfsMock::uvfsMock = nullptr; +thread_local bool UvfsMock::mockable = false; + +std::shared_ptr UvfsMock::GetMock() +{ + if (uvfsMock == nullptr) { + uvfsMock = std::make_shared(); + } + return uvfsMock; +} + +void UvfsMock::EnableMock() +{ + mockable = true; +} + +void UvfsMock::DisableMock() +{ + uvfsMock = nullptr; + mockable = false; +} + +bool UvfsMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +#ifdef __cplusplus +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) +{ + if (UvfsMock::IsMockable()) { + return UvfsMock::GetMock()->uv_fs_close(loop, req, file, cb); + } + + static int (*realUvFsClose)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb) = []() { + auto func = (int (*)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb))dlsym(RTLD_NEXT, "uv_fs_close"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real uv_fs_close: " << dlerror(); + } + return func; + }(); + + if (!realUvFsClose) { + return -1; + } + + return realUvFsClose(loop, req, file, cb); +} + +int uv_fs_fdatasync(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) +{ + if (UvfsMock::IsMockable()) { + return UvfsMock::GetMock()->uv_fs_fdatasync(loop, req, file, cb); + } + + static int (*realUvFsfdatasync)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb) = []() { + auto func = (int (*)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb))dlsym(RTLD_NEXT, "uv_fs_fdatasync"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real uv_fs_fdatasync: " << dlerror(); + } + return func; + }(); + + if (!realUvFsfdatasync) { + return -1; + } + + return realUvFsfdatasync(loop, req, file, cb); +} + +int uv_fs_unlink(uv_loop_t *loop, uv_fs_t *req, const char * file, uv_fs_cb cb) +{ + if (UvfsMock::IsMockable()) { + return UvfsMock::GetMock()->uv_fs_unlink(loop, req, file, cb); + } + + static int (*realUvFsUnlink)(uv_loop_t *, uv_fs_t *, const char *, uv_fs_cb) = []() { + auto func = (int (*)(uv_loop_t *, uv_fs_t *, const char *, uv_fs_cb))dlsym(RTLD_NEXT, "uv_fs_unlink"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real uv_fs_unlink: " << dlerror(); + } + return func; + }(); + + if (!realUvFsUnlink) { + return -1; + } + + return realUvFsUnlink(loop, req, file, cb); +} + +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..778012c36abbe9b622a5da831de21060fbe72d12 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h @@ -0,0 +1,56 @@ +/* + * 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_NAPI_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H +#define INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H + +#include "uv.h" +#include "filemgmt_libn.h" + +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; + +class IUvfsMock { +public: + virtual ~IUvfsMock() = default; + virtual int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) = 0; + virtual int uv_fs_fdatasync(uv_loop_t *loop, uv_fs_t *req, uv_file file, 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; +}; + +class UvfsMock : public IUvfsMock { +public: + MOCK_METHOD(int, uv_fs_close, (uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb), (override)); + MOCK_METHOD(int, uv_fs_fdatasync, (uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb), (override)); + MOCK_METHOD(int, uv_fs_unlink, (uv_loop_t *, uv_fs_t *, const char *, uv_fs_cb), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr uvfsMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp b/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4f57284de75603fab221e38784033f8db8cc60d --- /dev/null +++ b/interfaces/test/unittest/napi_js/prop_n_exporter_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 +#include +#include +#include +#include +#include "prop_n_exporter_mock.h" +#include "uv_fs_mock.h" +#include "prop_n_exporter.h" +#include "libn_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class PropNExporterMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +protected: + +}; + +void PropNExporterMockTest::SetUpTestCase(void) +{ + uvMock = make_shared(); + PropNExporterMock::EnableMock(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void PropNExporterMockTest::TearDownTestCase(void) +{ + uvMock = nullptr; + PropNExporterMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void PropNExporterMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + +} + +void PropNExporterMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: PropNExporterMockTest_UnlinkSync_001 + * @tc.desc: Test function of UnlinkSync() interface for failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + +*/ +HWTEST_F(PropNExporterMockTest, PropNExporterMockTest_UnlinkSync_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "PropNExporterMockTest-begin PropNExporterMockTest_UnlinkSync_001"; + napi_env env = reinterpret_cast(0x1000); + napi_value nv = reinterpret_cast(0x1200); + napi_callback_info mInfo = reinterpret_cast(0x1122); + + size_t strLen = 10; + auto strPtr = make_unique(strLen); + tuple, size_t> tp = { true, move(strPtr), 10 }; + + auto pMock = LibnMock::GetMock(); + EXPECT_CALL(*pMock, InitArgs(A())).WillOnce(Return(true)); + EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); + EXPECT_CALL(*pMock, ToUTF8StringPath()).WillOnce(Return(move(tp))); + EXPECT_CALL(*uvMock, uv_fs_unlink(_, _, _, _)).WillOnce(Return(-1)); + EXPECT_CALL(*pMock, ThrowErr(_)); + + auto res = PropNExporter::UnlinkSync(env, mInfo); + EXPECT_EQ(res, nullptr); + + GTEST_LOG_(INFO) << "PropNExporterMockTest-end PropNExporterMockTest_UnlinkSync_001"; +} + +} \ No newline at end of file