diff --git a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp index 11249146b64741b3e4c97b5622a886349de446b5..700daf1933c9befd45c701391b9a9b72f886af52 100644 --- a/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp +++ b/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp @@ -49,6 +49,8 @@ bool FileWatcher::InitNotify() eventFd_ = eventfd(0, EFD_CLOEXEC); if (eventFd_ < 0) { HILOGE("Failed to init eventfd errCode:%{public}d", errno); + close(notifyFd_); // Ignore the result of close + notifyFd_ = -1; return false; } return true; diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index 571257d363698ef167f4463f7d040ac556064589..f824a60a92be1d6e8fdee1a3814302f2133d78ac 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -327,11 +327,17 @@ 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/test/unittest/js/mod_fs/mock", + ] sources = [ "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp", "mod_fs/class_watcher/watcher_entity_test.cpp", + "mod_fs/mock/eventfd_mock.cpp", + "mod_fs/mock/inotify_mock.cpp", + "mod_fs/mock/unistd_mock.cpp", ] deps = [ @@ -342,6 +348,7 @@ ohos_unittest("napi_file_fs_test") { external_deps = [ "c_utils:utils", + "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", "libuv:uv", diff --git a/interfaces/test/unittest/js/mod_fs/class_watcher/watcher_entity_test.cpp b/interfaces/test/unittest/js/mod_fs/class_watcher/watcher_entity_test.cpp index 04dd5cd0fc847a0a58f3e4ce64135df6d0c2c558..f3924031b36ad9062b839a98a80229e6ea2d3d79 100644 --- a/interfaces/test/unittest/js/mod_fs/class_watcher/watcher_entity_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/class_watcher/watcher_entity_test.cpp @@ -15,8 +15,12 @@ #include "watcher_entity.h" +#include #include -#include + +#include "eventfd_mock.h" +#include "inotify_mock.h" +#include "unistd_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { @@ -41,13 +45,35 @@ void WatcherEntityTest::TearDownTestCase(void) void WatcherEntityTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; + EventfdMock::EnableMock(); + InotifyMock::EnableMock(); + UnistdMock::EnableMock(); + errno = 0; } void WatcherEntityTest::TearDown(void) { + // Reset all mocks + EventfdMock::DisableMock(); + InotifyMock::DisableMock(); + UnistdMock::DisableMock(); + // Reset FileWatcher stat + auto &watcher = FileWatcher::GetInstance(); + watcher.run_ = false; + watcher.reading_ = false; + watcher.closed_ = false; + watcher.notifyFd_ = -1; + watcher.eventFd_ = -1; + watcher.watcherInfoSet_.clear(); + watcher.wdFileNameMap_.clear(); GTEST_LOG_(INFO) << "TearDown"; } +inline const int32_t INITIALIZED_NOTIFYFD = 1; +inline const int32_t UNINITIALIZED_NOTIFYFD = -1; +inline const int32_t INITIALIZED_EVENTFD = 1; +inline const int32_t UNINITIALIZED_EVENTFD = -1; + /** * @tc.name: WatcherEntityTest_CloseNotifyFd_001 * @tc.desc: Test function of WatcherEntityTest::CloseNotifyFd interface for SUCCESS without close. @@ -78,6 +104,9 @@ HWTEST_F(WatcherEntityTest, WatcherEntityTest_CloseNotifyFd_002, testing::ext::T { GTEST_LOG_(INFO) << "WatcherEntityTest-begin WatcherEntityTest_CloseNotifyFd_002"; + EventfdMock::DisableMock(); + InotifyMock::DisableMock(); + UnistdMock::DisableMock(); auto &watcher = FileWatcher::GetInstance(); watcher.run_ = true; watcher.InitNotify(); @@ -98,6 +127,7 @@ HWTEST_F(WatcherEntityTest, WatcherEntityTest_CloseNotifyFd_003, testing::ext::T { GTEST_LOG_(INFO) << "WatcherEntityTest-begin WatcherEntityTest_CloseNotifyFd_003"; + UnistdMock::DisableMock(); auto &watcher = FileWatcher::GetInstance(); watcher.run_ = true; auto ret = watcher.CloseNotifyFd(); @@ -106,4 +136,98 @@ HWTEST_F(WatcherEntityTest, WatcherEntityTest_CloseNotifyFd_003, testing::ext::T GTEST_LOG_(INFO) << "WatcherEntityTest-end WatcherEntityTest_CloseNotifyFd_003"; } +/** + * @tc.name: WatcherEntityTest_InitNotify_001 + * @tc.desc: Test function of FileWatcher::InitNotify interface for SUCCESS. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherEntityTest, WatcherEntityTest_InitNotify_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherEntityTest-begin WatcherEntityTest_InitNotify_001"; + + // Prepare test condition + FileWatcher &watcher = FileWatcher::GetInstance(); + // Set mock behaviors + auto eventfdMock = EventfdMock::GetMock(); + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::Return(INITIALIZED_NOTIFYFD)); + EXPECT_CALL(*eventfdMock, eventfd(testing::_, testing::_)).Times(1).WillOnce(testing::Return(INITIALIZED_EVENTFD)); + // 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_, INITIALIZED_NOTIFYFD); + EXPECT_EQ(watcher.eventFd_, INITIALIZED_EVENTFD); + + GTEST_LOG_(INFO) << "WatcherEntityTest-end WatcherEntityTest_InitNotify_001"; +} + +/** + * @tc.name: WatcherEntityTest_InitNotify_002 + * @tc.desc: Test function of FileWatcher::InitNotify interface for FAILURE when inotify_init fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherEntityTest, WatcherEntityTest_InitNotify_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherEntityTest-begin WatcherEntityTest_InitNotify_002"; + + // Prepare test condition + FileWatcher &watcher = FileWatcher::GetInstance(); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, UNINITIALIZED_NOTIFYFD)); + // Do testing + bool result = watcher.InitNotify(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + EXPECT_FALSE(result); + EXPECT_EQ(watcher.notifyFd_, UNINITIALIZED_EVENTFD); + EXPECT_EQ(watcher.eventFd_, UNINITIALIZED_EVENTFD); + + GTEST_LOG_(INFO) << "WatcherEntityTest-end WatcherEntityTest_InitNotify_002"; +} + +/** + * @tc.name: WatcherEntityTest_InitNotify_003 + * @tc.desc: Test function of FileWatcher::InitNotify interface for FAILURE when eventfd fails. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(WatcherEntityTest, WatcherEntityTest_InitNotify_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "WatcherEntityTest-begin WatcherEntityTest_InitNotify_003"; + + // Prepare test condition + FileWatcher &watcher = FileWatcher::GetInstance(); + // Set mock behaviors + auto inotifyMock = InotifyMock::GetMock(); + auto eventfdMock = EventfdMock::GetMock(); + auto unistdMock = UnistdMock::GetMock(); + EXPECT_CALL(*inotifyMock, inotify_init()).Times(1).WillOnce(testing::Return(INITIALIZED_NOTIFYFD)); + EXPECT_CALL(*eventfdMock, eventfd(testing::_, testing::_)) + .Times(1) + .WillOnce(testing::SetErrnoAndReturn(EIO, UNINITIALIZED_EVENTFD)); + EXPECT_CALL(*unistdMock, close(testing::_)).Times(1).WillOnce(testing::Return(0)); + // Do testing + bool result = watcher.InitNotify(); + // Verify results + testing::Mock::VerifyAndClearExpectations(inotifyMock.get()); + testing::Mock::VerifyAndClearExpectations(eventfdMock.get()); + testing::Mock::VerifyAndClearExpectations(unistdMock.get()); + EXPECT_FALSE(result); + EXPECT_EQ(watcher.notifyFd_, UNINITIALIZED_EVENTFD); + EXPECT_EQ(watcher.eventFd_, UNINITIALIZED_EVENTFD); + + GTEST_LOG_(INFO) << "WatcherEntityTest-end WatcherEntityTest_InitNotify_003"; +} + } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file