blob: f4f818688fd1fd9ca54b562dd528969827283769 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "kudu/util/rolling_log.h"
#include <unistd.h>
#include <algorithm>
#include <cstdint>
#include <string>
#include <vector>
#include <glog/stl_logging.h>
#include <gtest/gtest.h>
#include "kudu/gutil/port.h"
#include "kudu/gutil/strings/stringpiece.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/gutil/strings/util.h"
#include "kudu/util/env.h"
#include "kudu/util/faststring.h"
#include "kudu/util/path_util.h"
#include "kudu/util/test_macros.h"
#include "kudu/util/test_util.h"
using std::string;
using std::vector;
using strings::Substitute;
namespace kudu {
class RollingLogTest : public KuduTest {
public:
RollingLogTest()
: log_dir_(GetTestPath("log_dir")) {
}
virtual void SetUp() OVERRIDE {
ASSERT_OK(env_->CreateDir(log_dir_));
}
protected:
void AssertLogCount(int expected_count, vector<string>* children) {
vector<string> dir_entries;
ASSERT_OK(env_->GetChildren(log_dir_, &dir_entries));
children->clear();
for (const string& child : dir_entries) {
if (child == "." || child == "..") continue;
children->push_back(child);
ASSERT_TRUE(HasPrefixString(child, "rolling_log-test."));
ASSERT_STR_CONTAINS(child, ".mylog.");
string pid_suffix = Substitute("$0", getpid());
ASSERT_TRUE(HasSuffixString(child, pid_suffix) ||
HasSuffixString(child, pid_suffix + ".gz")) << "bad child: " << child;
}
std::sort(children->begin(), children->end());
ASSERT_EQ(children->size(), expected_count) << *children;
}
const string log_dir_;
};
// Test with compression off.
TEST_F(RollingLogTest, TestLog) {
RollingLog log(env_, log_dir_, "mylog");
log.SetCompressionEnabled(false);
log.SetRollThresholdBytes(100);
// Before writing anything, we shouldn't open a log file.
vector<string> children;
NO_FATALS(AssertLogCount(0, &children));
// Appending some data should write a new segment.
const string kTestString = "Hello world\n";
ASSERT_OK(log.Append(kTestString));
NO_FATALS(AssertLogCount(1, &children));
for (int i = 0; i < 10; i++) {
ASSERT_OK(log.Append(kTestString));
}
NO_FATALS(AssertLogCount(2, &children));
faststring data;
string path = JoinPathSegments(log_dir_, children[0]);
ASSERT_OK(ReadFileToString(env_, path, &data));
ASSERT_TRUE(HasPrefixString(data.ToString(), kTestString))
<< "Data missing";
ASSERT_LE(data.size(), 100 + kTestString.length())
<< "Roll threshold not respected";
}
// Test with compression on.
TEST_F(RollingLogTest, TestCompression) {
RollingLog log(env_, log_dir_, "mylog");
ASSERT_OK(log.Open());
StringPiece data = "Hello world\n";
int raw_size = 0;
for (int i = 0; i < 1000; i++) {
ASSERT_OK(log.Append(data));
raw_size += data.size();
}
ASSERT_OK(log.Close());
vector<string> children;
NO_FATALS(AssertLogCount(1, &children));
ASSERT_TRUE(HasSuffixString(children[0], ".gz"));
// Ensure that the output is actually gzipped.
uint64_t size;
ASSERT_OK(env_->GetFileSize(JoinPathSegments(log_dir_, children[0]), &size));
ASSERT_LT(size, raw_size / 10);
ASSERT_GT(size, 0);
}
TEST_F(RollingLogTest, TestFileCountLimit) {
RollingLog log(env_, log_dir_, "mylog");
ASSERT_OK(log.Open());
log.SetRollThresholdBytes(100);
log.SetMaxNumSegments(3);
for (int i = 0; i < 100; i++) {
ASSERT_OK(log.Append("hello world\n"));
}
ASSERT_OK(log.Close());
vector<string> children;
NO_FATALS(AssertLogCount(3, &children));
}
} // namespace kudu