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