// Copyright (C) 2019 The Android Open Source Project // // 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 using namespace std::literals; using android::base::unique_fd; using android::fs_mgr::WaitForFile; using android::fs_mgr::WaitForFileDeleted; class FileWaitTest : public ::testing::Test { protected: void SetUp() override { const ::testing::TestInfo* tinfo = ::testing::UnitTest::GetInstance()->current_test_info(); test_file_ = temp_dir_.path + "/"s + tinfo->name(); } void TearDown() override { unlink(test_file_.c_str()); } TemporaryDir temp_dir_; std::string test_file_; }; TEST_F(FileWaitTest, FileExists) { unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700)); ASSERT_GE(fd, 0); ASSERT_TRUE(WaitForFile(test_file_, 500ms)); ASSERT_FALSE(WaitForFileDeleted(test_file_, 500ms)); } TEST_F(FileWaitTest, FileDoesNotExist) { ASSERT_FALSE(WaitForFile(test_file_, 500ms)); ASSERT_TRUE(WaitForFileDeleted(test_file_, 500ms)); } TEST_F(FileWaitTest, CreateAsync) { std::thread thread([this] { std::this_thread::sleep_for(std::chrono::seconds(1)); unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700)); }); EXPECT_TRUE(WaitForFile(test_file_, 3s)); thread.join(); } TEST_F(FileWaitTest, CreateOtherAsync) { std::thread thread([this] { std::this_thread::sleep_for(std::chrono::seconds(1)); unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700)); }); EXPECT_FALSE(WaitForFile(test_file_ + ".wontexist", 2s)); thread.join(); } TEST_F(FileWaitTest, DeleteAsync) { // Note: need to close the file, otherwise inotify considers it not deleted. { unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700)); ASSERT_GE(fd, 0); } std::thread thread([this] { std::this_thread::sleep_for(std::chrono::seconds(1)); unlink(test_file_.c_str()); }); EXPECT_TRUE(WaitForFileDeleted(test_file_, 3s)); thread.join(); } TEST_F(FileWaitTest, BadPath) { ASSERT_FALSE(WaitForFile("/this/path/does/not/exist", 5ms)); EXPECT_EQ(errno, ENOENT); }