#include <memory>
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "build/chromeos_buildflags.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/logging_chrome.h"
#include "content/public/common/content_switches.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
class ChromeLoggingTest : public testing::Test { … };
TEST_F(ChromeLoggingTest, LogFileName) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(ChromeLoggingTest, EnvironmentLogFileName) {
SaveEnvironmentVariable("c:\\path\\test env value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_NE(base::FilePath::StringType::npos,
filename.value().find(FILE_PATH_LITERAL("test env value")));
ASSERT_TRUE(filename.IsAbsolute());
RestoreEnvironmentVariable();
}
#else
TEST_F(ChromeLoggingTest, EnvironmentLogFileName) { … }
#endif
#if BUILDFLAG(IS_WIN)
TEST_F(ChromeLoggingTest, FlagLogFileName) {
SetLogFileFlag("c:\\path\\test flag value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_NE(base::FilePath::StringType::npos,
filename.value().find(FILE_PATH_LITERAL("test flag value")));
ASSERT_TRUE(filename.IsAbsolute());
}
TEST_F(ChromeLoggingTest, FlagLogFileNameNonAbsolute) {
SetLogFileFlag("test file value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_NE(base::FilePath::StringType::npos,
filename.value().find(FILE_PATH_LITERAL("chrome_debug.log")));
ASSERT_TRUE(filename.IsAbsolute());
}
#else
TEST_F(ChromeLoggingTest, FlagLogFileName) { … }
#endif
#if BUILDFLAG(IS_WIN)
TEST_F(ChromeLoggingTest, EnvironmentAndFlagLogFileName) {
SaveEnvironmentVariable("c:\\path\\test env value");
SetLogFileFlag("d:\\path\\test flag value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_NE(base::FilePath::StringType::npos,
filename.value().find(FILE_PATH_LITERAL("test flag value")));
ASSERT_TRUE(filename.IsAbsolute());
RestoreEnvironmentVariable();
}
#else
TEST_F(ChromeLoggingTest, EnvironmentAndFlagLogFileName) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(ChromeLoggingTest, TimestampedName) {
base::FilePath path = base::FilePath(FILE_PATH_LITERAL("xy.zzy"));
base::FilePath timestamped_path =
logging::GenerateTimestampedName(path, base::Time::Now());
EXPECT_THAT(timestamped_path.value(),
::testing::MatchesRegex("^xy_\\d+-\\d+\\.zzy$"));
}
TEST_F(ChromeLoggingTest, SetUpSymlink) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath temp_dir_path = temp_dir.GetPath();
base::FilePath bare_symlink_path =
temp_dir_path.AppendASCII("chrome-test-log");
base::FilePath latest_symlink_path =
temp_dir_path.AppendASCII("chrome-test-log.LATEST");
base::FilePath previous_symlink_path =
temp_dir_path.AppendASCII("chrome-test-log.PREVIOUS");
base::FilePath old_target_path = logging::GenerateTimestampedName(
bare_symlink_path, base::Time::UnixEpoch());
ASSERT_TRUE(base::CreateSymbolicLink(old_target_path, bare_symlink_path));
logging::SetUpSymlinkIfNeeded(latest_symlink_path,
true);
base::FilePath target_path;
ASSERT_TRUE(base::ReadSymbolicLink(bare_symlink_path, &target_path));
EXPECT_EQ(target_path.value(), latest_symlink_path.value());
base::FilePath latest_target_path;
ASSERT_TRUE(base::ReadSymbolicLink(latest_symlink_path, &latest_target_path));
EXPECT_NE(latest_target_path.value(), old_target_path.value());
EXPECT_THAT(latest_target_path.value(),
::testing::MatchesRegex("^.*chrome-test-log_\\d+-\\d+$"));
logging::SetUpSymlinkIfNeeded(latest_symlink_path, true);
ASSERT_TRUE(base::ReadSymbolicLink(previous_symlink_path, &target_path));
EXPECT_EQ(target_path.value(), latest_target_path.value());
ASSERT_TRUE(base::ReadSymbolicLink(latest_symlink_path, &latest_target_path));
EXPECT_THAT(latest_target_path.value(),
::testing::MatchesRegex("^.*chrome-test-log_\\d+-\\d+$"));
}
TEST_F(ChromeLoggingTest, RotateLogFiles) {
constexpr char kLog1Content[] = "log#1\n";
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath temp_dir_path = temp_dir.GetPath();
base::FilePath log_path_latest = temp_dir_path.AppendASCII("chrome-test-log");
ASSERT_TRUE(base::WriteFile(log_path_latest, kLog1Content));
base::File::Info file_info;
base::File(log_path_latest, base::File::FLAG_OPEN | base::File::FLAG_READ)
.GetInfo(&file_info);
base::Time creation_time = file_info.creation_time;
base::FilePath expected_rotated_path =
logging::GenerateTimestampedName(log_path_latest, creation_time);
{
EXPECT_TRUE(base::PathExists(log_path_latest));
EXPECT_FALSE(base::PathExists(expected_rotated_path));
}
ASSERT_TRUE(logging::RotateLogFile(log_path_latest));
{
EXPECT_FALSE(base::PathExists(log_path_latest));
EXPECT_TRUE(base::PathExists(expected_rotated_path));
std::string buffer;
base::ReadFileToString(expected_rotated_path, &buffer);
EXPECT_EQ(buffer, kLog1Content);
}
}
TEST_F(ChromeLoggingTest, RotateLogFilesNoFile) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath temp_dir_path = temp_dir.GetPath();
base::FilePath log_path_latest = temp_dir_path.AppendASCII("chrome-test-log");
{
EXPECT_FALSE(base::PathExists(log_path_latest));
base::FileEnumerator enumerator(temp_dir_path, true,
base::FileEnumerator::FILES);
EXPECT_TRUE(enumerator.Next().empty());
}
ASSERT_TRUE(logging::RotateLogFile(log_path_latest));
{
EXPECT_FALSE(base::PathExists(log_path_latest));
base::FileEnumerator enumerator(temp_dir_path, true,
base::FileEnumerator::FILES);
EXPECT_TRUE(enumerator.Next().empty());
}
}
TEST_F(ChromeLoggingTest, RotateLogFilesExisting) {
constexpr char kLatestLogContent[] = "log#1\n";
constexpr char kOldLogContent[] = "log#2\n";
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath temp_dir_path = temp_dir.GetPath();
base::FilePath log_path_latest = temp_dir_path.AppendASCII("chrome-test-log");
ASSERT_TRUE(base::WriteFile(log_path_latest, kLatestLogContent));
base::File::Info file_info;
{
base::File(log_path_latest, base::File::FLAG_OPEN | base::File::FLAG_READ)
.GetInfo(&file_info);
}
base::Time creation_time = file_info.creation_time;
base::FilePath exist_log_path =
logging::GenerateTimestampedName(log_path_latest, creation_time);
ASSERT_TRUE(base::WriteFile(exist_log_path, kOldLogContent));
base::FilePath rotated_log_path = logging::GenerateTimestampedName(
log_path_latest, creation_time + base::Seconds(1));
{
EXPECT_TRUE(base::PathExists(log_path_latest));
EXPECT_TRUE(base::PathExists(exist_log_path));
EXPECT_FALSE(base::PathExists(rotated_log_path));
}
ASSERT_TRUE(logging::RotateLogFile(log_path_latest));
{
EXPECT_FALSE(base::PathExists(log_path_latest));
EXPECT_TRUE(base::PathExists(exist_log_path));
EXPECT_TRUE(base::PathExists(rotated_log_path));
std::string buffer;
base::ReadFileToString(exist_log_path, &buffer);
EXPECT_EQ(buffer, kOldLogContent);
base::ReadFileToString(rotated_log_path, &buffer);
EXPECT_EQ(buffer, kLatestLogContent);
}
}
#endif