blob: f65e1415f761e31520078792031142fe0270c37d [file] [log] [blame]
// Copyright 2013 The Chromium 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 <memory>
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.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 {
public:
// Stores the current value of the log file name environment
// variable and sets the variable to new_value.
void SaveEnvironmentVariable(const std::string& new_value) {
std::unique_ptr<base::Environment> env(base::Environment::Create());
if (!env->GetVar(env_vars::kLogFileName, &environment_filename_))
environment_filename_ = "";
env->SetVar(env_vars::kLogFileName, new_value);
}
// Restores the value of the log file nave environment variable
// previously saved by SaveEnvironmentVariable().
void RestoreEnvironmentVariable() {
std::unique_ptr<base::Environment> env(base::Environment::Create());
env->SetVar(env_vars::kLogFileName, environment_filename_);
}
void SetLogFileFlag(const std::string& value) {
cmd_line_.AppendSwitchASCII(switches::kLogFile, value);
}
const base::CommandLine& cmd_line() { return cmd_line_; }
private:
std::string environment_filename_; // Saves real environment value.
base::CommandLine cmd_line_ =
base::CommandLine(base::CommandLine::NO_PROGRAM);
};
// Tests the log file name getter without an environment variable.
TEST_F(ChromeLoggingTest, LogFileName) {
SaveEnvironmentVariable(std::string());
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_NE(base::FilePath::StringType::npos,
filename.value().find(FILE_PATH_LITERAL("chrome_debug.log")));
RestoreEnvironmentVariable();
}
// Tests the log file name getter with an environment variable.
TEST_F(ChromeLoggingTest, EnvironmentLogFileName) {
SaveEnvironmentVariable("test env value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("test env value")).value(),
filename.value());
RestoreEnvironmentVariable();
}
// Tests the log file name getter with a command-line flag.
TEST_F(ChromeLoggingTest, FlagLogFileName) {
SetLogFileFlag("test flag value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("test flag value")).value(),
filename.value());
}
// Tests the log file name getter with with an environment variable and a
// command-line flag. The flag takes precedence.
TEST_F(ChromeLoggingTest, EnvironmentAndFlagLogFileName) {
SaveEnvironmentVariable("test env value");
SetLogFileFlag("test flag value");
base::FilePath filename = logging::GetLogFileName(cmd_line());
ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("test flag value")).value(),
filename.value());
RestoreEnvironmentVariable();
}
#if defined(OS_CHROMEOS)
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.Append(FILE_PATH_LITERAL("chrome-test-log"));
base::FilePath latest_symlink_path =
temp_dir_path.Append(FILE_PATH_LITERAL("chrome-test-log.LATEST"));
base::FilePath previous_symlink_path =
temp_dir_path.Append(FILE_PATH_LITERAL("chrome-test-log.PREVIOUS"));
// Start from a legacy situation, where "chrome-test-log" is a symlink
// pointing to the latest log, which has a time-stamped name from a while
// ago.
base::FilePath old_target_path = logging::GenerateTimestampedName(
bare_symlink_path, base::Time::UnixEpoch());
ASSERT_TRUE(base::CreateSymbolicLink(old_target_path, bare_symlink_path));
// Call the testee with the new symlink path, as if starting a new session.
logging::SetUpSymlinkIfNeeded(latest_symlink_path,
/*start_new_log=*/true);
// We now expect:
//
// chrome-test-log --> chrome-test-log.LATEST
// chrome-test-log.LATEST --> <new time-stamped path>
// no chrome-test-log.PREVIOUS on the legacy transition.
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+$"));
// Simulate one more session cycle.
logging::SetUpSymlinkIfNeeded(latest_symlink_path, /*start_new_log=*/true);
// We now expect:
//
// chrome-test-log.PREVIOUS --> <previous target of chrome-test-log.LATEST>
//
// We also expect that the .LATEST file is now pointing to a file with a
// newer time stamp. Unfortunately it's probably not newer enough to tell
// the difference since the time stamp granularity is 1 second.
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+$"));
}
#endif // defined(OS_CHROMEOS)