blob: 9d541bd2bd9885f973ca8ae89533008c1fb4f37c [file] [log] [blame]
// 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