blob: 0843340dfd8262277f60156a796caaaf724e8ebb [file] [log] [blame]
// Copyright 2020 The ChromiumOS Authors
// 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/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.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) {
constexpr base::TimeDelta kTinyTimeout = base::Milliseconds(100);
int max_try = 50;
while (counter() < target_value) {
base::PlatformThread::Sleep(kTinyTimeout);
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