| // Copyright 2020 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "croslog/file_change_watcher.h" |
| |
| #include <string> |
| |
| #include "base/bind.h" |
| #include "base/files/file.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/run_loop.h" |
| #include "gtest/gtest.h" |
| |
| namespace croslog { |
| |
| class FileChangeWatcherTest : public ::testing::Test, |
| public FileChangeWatcher::Observer { |
| public: |
| FileChangeWatcherTest() = default; |
| FileChangeWatcherTest(const FileChangeWatcherTest&) = delete; |
| FileChangeWatcherTest& operator=(const FileChangeWatcherTest&) = delete; |
| |
| ~FileChangeWatcherTest() override = default; |
| |
| void OnFileContentMaybeChanged() override { counter_++; } |
| void OnFileNameMaybeChanged() override {} |
| |
| bool WaitForCounterValue(uint32_t target_value) { |
| const int kTinyTimeoutMs = 100; |
| int max_try = 50; |
| while (counter() < target_value) { |
| base::PlatformThread::Sleep( |
| base::TimeDelta::FromMilliseconds(kTinyTimeoutMs)); |
| base::RunLoop().RunUntilIdle(); |
| if (--max_try == 0) |
| return false; |
| } |
| return true; |
| } |
| |
| uint32_t counter() const { return counter_; } |
| |
| private: |
| uint32_t counter_ = 0; |
| }; |
| |
| TEST_F(FileChangeWatcherTest, FileChange) { |
| base::FilePath mount_info; |
| std::string test_string = "test"; |
| |
| FileChangeWatcher* watcher = FileChangeWatcher::GetInstance(); |
| |
| EXPECT_TRUE(base::CreateTemporaryFile(&mount_info)); |
| EXPECT_TRUE(watcher->AddWatch(mount_info, this)); |
| |
| // Open the temporary file and write something twice. |
| { |
| // Open |
| base::File file(mount_info, base::File::FLAG_OPEN | base::File::FLAG_WRITE); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_EQ(0u, counter()); |
| |
| // Write |
| uint32_t previous_counter = counter(); |
| EXPECT_EQ(file.WriteAtCurrentPos(test_string.c_str(), test_string.length()), |
| test_string.length()); |
| EXPECT_TRUE(WaitForCounterValue(previous_counter + 1u)); |
| |
| // Write (append) |
| previous_counter = counter(); |
| EXPECT_EQ(file.WriteAtCurrentPos(test_string.c_str(), test_string.length()), |
| test_string.length()); |
| EXPECT_TRUE(WaitForCounterValue(previous_counter + 1u)); |
| |
| // Close |
| previous_counter = counter(); |
| file.Close(); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_EQ(previous_counter, counter()); |
| } |
| |
| // Open the temporary file again and append something twice. |
| { |
| // Open |
| uint32_t previous_counter = counter(); |
| base::File file(mount_info, base::File::FLAG_OPEN | base::File::FLAG_WRITE | |
| base::File::FLAG_APPEND); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_EQ(previous_counter, counter()); |
| |
| // Write (append) |
| previous_counter = counter(); |
| EXPECT_EQ(file.WriteAtCurrentPos(test_string.c_str(), test_string.length()), |
| test_string.length()); |
| EXPECT_TRUE(WaitForCounterValue(previous_counter + 1u)); |
| |
| // Close |
| previous_counter = counter(); |
| file.Close(); |
| base::RunLoop().RunUntilIdle(); |
| EXPECT_EQ(previous_counter, counter()); |
| } |
| |
| watcher->RemoveWatch(mount_info); |
| } |
| |
| } // namespace croslog |