blob: 50db49745e133461f0dc9662b7538e0d7b186005 [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 "vm_tools/syslog/rotator.h"
#include <string>
#include <vector>
#include <base/check.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 <base/format_macros.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace vm_tools {
namespace syslog {
class RotatorTest : public ::testing::Test {
public:
RotatorTest() {
CHECK(scoped_temp_dir_.CreateUniqueTempDir());
root_path_ = scoped_temp_dir_.GetPath();
}
void TearDown() override {}
void GetFileNames(const std::string& pattern,
std::vector<std::string>* names) {
std::vector<base::FileEnumerator::FileInfo> file_info;
Rotator::GetSortedFileInfo(root_path_, pattern, &file_info);
for (const auto& info : file_info) {
names->push_back(info.GetName().BaseName().value());
}
}
void WriteFileSequence(const std::string& base_name, int max_index) {
for (int i = 0; i < max_index; ++i) {
base::FilePath file_path = root_path_.Append(base_name);
if (i > 0) {
file_path = file_path.AddExtension(base::NumberToString(i));
}
if (base::WriteFile(file_path, file_path.value())) {
VLOG(1) << "Wrote " << file_path.value().size() << " bytes to "
<< file_path;
} else {
VLOG(1) << "Unable to write to " << file_path;
}
}
}
protected:
base::FilePath root_path_;
private:
base::ScopedTempDir scoped_temp_dir_;
};
TEST_F(RotatorTest, RotateEmptyDir) {
EXPECT_TRUE(base::IsDirectoryEmpty(root_path_));
Rotator rotator;
rotator.RotateLogFiles(root_path_, 0);
EXPECT_TRUE(base::IsDirectoryEmpty(root_path_));
}
TEST_F(RotatorTest, RotateNonLogDir) {
EXPECT_TRUE(base::IsDirectoryEmpty(root_path_));
WriteFileSequence("foo", 20);
EXPECT_FALSE(base::IsDirectoryEmpty(root_path_));
Rotator rotator;
rotator.RotateLogFiles(root_path_, 10);
EXPECT_FALSE(base::IsDirectoryEmpty(root_path_));
std::vector<std::string> names;
GetFileNames("foo*", &names);
EXPECT_EQ(20, names.size());
EXPECT_THAT(names, testing::ElementsAre(
"foo.19", "foo.18", "foo.17", "foo.16", "foo.15",
"foo.14", "foo.13", "foo.12", "foo.11", "foo.10",
"foo.9", "foo.8", "foo.7", "foo.6", "foo.5", "foo.4",
"foo.3", "foo.2", "foo.1", "foo"));
}
TEST_F(RotatorTest, RotateUnderfullDir) {
EXPECT_TRUE(base::IsDirectoryEmpty(root_path_));
WriteFileSequence("vm_foo.log", 5);
EXPECT_FALSE(base::IsDirectoryEmpty(root_path_));
Rotator rotator;
rotator.RotateLogFiles(root_path_, 10);
EXPECT_FALSE(base::IsDirectoryEmpty(root_path_));
std::vector<std::string> names;
GetFileNames("vm_foo.log*", &names);
EXPECT_EQ(5, names.size());
EXPECT_THAT(names, testing::ElementsAre("vm_foo.log.5", "vm_foo.log.4",
"vm_foo.log.3", "vm_foo.log.2",
"vm_foo.log.1"));
}
TEST_F(RotatorTest, RotateOverfullDir) {
EXPECT_TRUE(base::IsDirectoryEmpty(root_path_));
WriteFileSequence("vm_foo.log", 20);
WriteFileSequence("crosvm.log", 6);
Rotator rotator;
rotator.RotateLogFiles(root_path_, 10);
EXPECT_FALSE(base::IsDirectoryEmpty(root_path_));
std::vector<std::string> vm_foo_names;
GetFileNames("vm_foo.log*", &vm_foo_names);
EXPECT_EQ(10, vm_foo_names.size());
EXPECT_THAT(vm_foo_names, testing::ElementsAre(
"vm_foo.log.10", "vm_foo.log.9", "vm_foo.log.8",
"vm_foo.log.7", "vm_foo.log.6", "vm_foo.log.5",
"vm_foo.log.4", "vm_foo.log.3", "vm_foo.log.2",
"vm_foo.log.1"));
std::vector<std::string> crosvm_names;
GetFileNames("crosvm.log*", &crosvm_names);
EXPECT_EQ(6, crosvm_names.size());
EXPECT_THAT(
crosvm_names,
testing::ElementsAre("crosvm.log.6", "crosvm.log.5", "crosvm.log.4",
"crosvm.log.3", "crosvm.log.2", "crosvm.log.1"));
}
TEST_F(RotatorTest, RotateTimestampedNamedSequence) {
EXPECT_TRUE(base::IsDirectoryEmpty(root_path_));
int64_t ts0 = 12345670;
for (int i = 0; i < 10; ++i) {
base::FilePath file_path = root_path_.Append(
base::StringPrintf("encoded-termina-%" PRId64 ".log", ts0 + i));
if (i > 0) {
file_path = file_path.AddExtension(base::NumberToString(i));
}
ASSERT_TRUE(base::WriteFile(file_path, file_path.value()));
VLOG(1) << "Wrote " << file_path.value().size() << " bytes to "
<< file_path;
}
Rotator rotator;
rotator.RotateLogFiles(root_path_, 6);
EXPECT_FALSE(base::IsDirectoryEmpty(root_path_));
std::vector<std::string> termina_names;
GetFileNames("encoded-termina*.log*", &termina_names);
EXPECT_EQ(6, termina_names.size());
EXPECT_THAT(
termina_names,
testing::ElementsAre(
"encoded-termina-12345675.log.6", "encoded-termina-12345674.log.5",
"encoded-termina-12345673.log.4", "encoded-termina-12345672.log.3",
"encoded-termina-12345671.log.2", "encoded-termina-12345670.log.1"));
}
} // namespace syslog
} // namespace vm_tools