1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <chrono>
16 #include <string>
17 #include <thread>
18
19 #include <android-base/file.h>
20 #include <android-base/unique_fd.h>
21 #include <fs_mgr/file_wait.h>
22 #include <gtest/gtest.h>
23
24 using namespace std::literals;
25 using android::base::unique_fd;
26 using android::fs_mgr::WaitForFile;
27 using android::fs_mgr::WaitForFileDeleted;
28
29 class FileWaitTest : public ::testing::Test {
30 protected:
SetUp()31 void SetUp() override {
32 const ::testing::TestInfo* tinfo = ::testing::UnitTest::GetInstance()->current_test_info();
33 test_file_ = temp_dir_.path + "/"s + tinfo->name();
34 }
35
TearDown()36 void TearDown() override { unlink(test_file_.c_str()); }
37
38 TemporaryDir temp_dir_;
39 std::string test_file_;
40 };
41
TEST_F(FileWaitTest,FileExists)42 TEST_F(FileWaitTest, FileExists) {
43 unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700));
44 ASSERT_GE(fd, 0);
45
46 ASSERT_TRUE(WaitForFile(test_file_, 500ms));
47 ASSERT_FALSE(WaitForFileDeleted(test_file_, 500ms));
48 }
49
TEST_F(FileWaitTest,FileDoesNotExist)50 TEST_F(FileWaitTest, FileDoesNotExist) {
51 ASSERT_FALSE(WaitForFile(test_file_, 500ms));
52 ASSERT_TRUE(WaitForFileDeleted(test_file_, 500ms));
53 }
54
TEST_F(FileWaitTest,CreateAsync)55 TEST_F(FileWaitTest, CreateAsync) {
56 std::thread thread([this] {
57 std::this_thread::sleep_for(std::chrono::seconds(1));
58 unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700));
59 });
60 EXPECT_TRUE(WaitForFile(test_file_, 3s));
61 thread.join();
62 }
63
TEST_F(FileWaitTest,CreateOtherAsync)64 TEST_F(FileWaitTest, CreateOtherAsync) {
65 std::thread thread([this] {
66 std::this_thread::sleep_for(std::chrono::seconds(1));
67 unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700));
68 });
69 EXPECT_FALSE(WaitForFile(test_file_ + ".wontexist", 2s));
70 thread.join();
71 }
72
TEST_F(FileWaitTest,DeleteAsync)73 TEST_F(FileWaitTest, DeleteAsync) {
74 // Note: need to close the file, otherwise inotify considers it not deleted.
75 {
76 unique_fd fd(open(test_file_.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0700));
77 ASSERT_GE(fd, 0);
78 }
79
80 std::thread thread([this] {
81 std::this_thread::sleep_for(std::chrono::seconds(1));
82 unlink(test_file_.c_str());
83 });
84 EXPECT_TRUE(WaitForFileDeleted(test_file_, 3s));
85 thread.join();
86 }
87
TEST_F(FileWaitTest,BadPath)88 TEST_F(FileWaitTest, BadPath) {
89 ASSERT_FALSE(WaitForFile("/this/path/does/not/exist", 5ms));
90 EXPECT_EQ(errno, ENOENT);
91 }
92