@ -17,6 +17,7 @@
# include <string>
# include <string>
# include <thread>
# include <thread>
# include <vector>
# include <vector>
# include "db/db_test_util.h"
# include "port/port.h"
# include "port/port.h"
# include "rocksdb/db.h"
# include "rocksdb/db.h"
# include "util/logging.h"
# include "util/logging.h"
@ -24,6 +25,22 @@
# include "util/testharness.h"
# include "util/testharness.h"
namespace rocksdb {
namespace rocksdb {
namespace {
class NoSleepEnv : public EnvWrapper {
public :
NoSleepEnv ( Env * base ) : EnvWrapper ( base ) { }
virtual void SleepForMicroseconds ( int micros ) override {
fake_time_ + = static_cast < uint64_t > ( micros ) ;
}
virtual uint64_t NowNanos ( ) override { return fake_time_ * 1000 ; }
virtual uint64_t NowMicros ( ) override { return fake_time_ ; }
private :
uint64_t fake_time_ = 6666666666 ;
} ;
} // namespace
class AutoRollLoggerTest : public testing : : Test {
class AutoRollLoggerTest : public testing : : Test {
public :
public :
@ -44,13 +61,13 @@ class AutoRollLoggerTest : public testing::Test {
void RollLogFileBySizeTest ( AutoRollLogger * logger , size_t log_max_size ,
void RollLogFileBySizeTest ( AutoRollLogger * logger , size_t log_max_size ,
const std : : string & log_message ) ;
const std : : string & log_message ) ;
uint64_t RollLogFileByTimeTest ( AutoRollLogger * logger , size_t time ,
void RollLogFileByTimeTest ( Env * , AutoRollLogger * logger , size_t time ,
const std : : string & log_message ) ;
const std : : string & log_message ) ;
static const std : : string kSampleMessage ;
static const std : : string kSampleMessage ;
static const std : : string kTestDir ;
static const std : : string kTestDir ;
static const std : : string kLogFile ;
static const std : : string kLogFile ;
static Env * env ;
static Env * default_ env;
} ;
} ;
const std : : string AutoRollLoggerTest : : kSampleMessage (
const std : : string AutoRollLoggerTest : : kSampleMessage (
@ -58,7 +75,7 @@ const std::string AutoRollLoggerTest::kSampleMessage(
const std : : string AutoRollLoggerTest : : kTestDir ( test : : TmpDir ( ) + " /db_log_test " ) ;
const std : : string AutoRollLoggerTest : : kTestDir ( test : : TmpDir ( ) + " /db_log_test " ) ;
const std : : string AutoRollLoggerTest : : kLogFile ( test : : TmpDir ( ) +
const std : : string AutoRollLoggerTest : : kLogFile ( test : : TmpDir ( ) +
" /db_log_test/LOG " ) ;
" /db_log_test/LOG " ) ;
Env * AutoRollLoggerTest : : env = Env : : Default ( ) ;
Env * AutoRollLoggerTest : : default_ env = Env : : Default ( ) ;
// In this test we only want to Log some simple log message with
// In this test we only want to Log some simple log message with
// no format. LogMessage() provides such a simple interface and
// no format. LogMessage() provides such a simple interface and
@ -75,16 +92,6 @@ void LogMessage(const InfoLogLevel log_level, Logger* logger,
}
}
} // namespace
} // namespace
namespace {
void GetFileCreateTime ( const std : : string & fname , uint64_t * file_ctime ) {
struct stat s ;
if ( stat ( fname . c_str ( ) , & s ) ! = 0 ) {
* file_ctime = ( uint64_t ) 0 ;
}
* file_ctime = static_cast < uint64_t > ( s . st_ctime ) ;
}
} // namespace
void AutoRollLoggerTest : : RollLogFileBySizeTest ( AutoRollLogger * logger ,
void AutoRollLoggerTest : : RollLogFileBySizeTest ( AutoRollLogger * logger ,
size_t log_max_size ,
size_t log_max_size ,
const std : : string & log_message ) {
const std : : string & log_message ) {
@ -111,45 +118,42 @@ void AutoRollLoggerTest::RollLogFileBySizeTest(AutoRollLogger* logger,
ASSERT_TRUE ( message_size = = logger - > GetLogFileSize ( ) ) ;
ASSERT_TRUE ( message_size = = logger - > GetLogFileSize ( ) ) ;
}
}
uint64_t AutoRollLoggerTest : : RollLogFileByTimeTest (
void AutoRollLoggerTest : : RollLogFileByTimeTest ( Env * env , AutoRollLogger * logger ,
AutoRollLogger * logger , size_t time , const std : : string & log_message ) {
size_t time ,
uint64_t expected_create_time ;
const std : : string & log_message ) {
uint64_t actual_create_time ;
uint64_t expected_ctime ;
uint64_t actual_ctime ;
uint64_t total_log_size ;
uint64_t total_log_size ;
EXPECT_OK ( env - > GetFileSize ( kLogFile , & total_log_size ) ) ;
EXPECT_OK ( env - > GetFileSize ( kLogFile , & total_log_size ) ) ;
GetFileCreateTime ( kLogFile , & expected_create_time ) ;
expected_ctime = logger - > TEST_ctime ( ) ;
logger - > SetCallNowMicrosEveryNRecords ( 0 ) ;
logger - > SetCallNowMicrosEveryNRecords ( 0 ) ;
// -- Write to the log for several times, which is supposed
// -- Write to the log for several times, which is supposed
// to be finished before time.
// to be finished before time.
for ( int i = 0 ; i < 10 ; + + i ) {
for ( int i = 0 ; i < 10 ; + + i ) {
LogMessage ( logger , log_message . c_str ( ) ) ;
env - > SleepForMicroseconds ( 50000 ) ;
EXPECT_OK ( logger - > GetStatus ( ) ) ;
LogMessage ( logger , log_message . c_str ( ) ) ;
// Make sure we always write to the same log file (by
EXPECT_OK ( logger - > GetStatus ( ) ) ;
// checking the create time);
// Make sure we always write to the same log file (by
GetFileCreateTime ( kLogFile , & actual_create_time ) ;
// checking the create time);
// Also make sure the log size is increasing.
actual_ctime = logger - > TEST_ctime ( ) ;
EXPECT_EQ ( expected_create_time , actual_create_time ) ;
EXPECT_GT ( logger - > GetLogFileSize ( ) , total_log_size ) ;
// Also make sure the log size is increasing.
total_log_size = logger - > GetLogFileSize ( ) ;
EXPECT_EQ ( expected_ctime , actual_ctime ) ;
EXPECT_GT ( logger - > GetLogFileSize ( ) , total_log_size ) ;
total_log_size = logger - > GetLogFileSize ( ) ;
}
}
// -- Make the log file expire
// -- Make the log file expire
# ifdef OS_WIN
env - > SleepForMicroseconds ( static_cast < int > ( time * 1000000 ) ) ;
Sleep ( static_cast < unsigned int > ( time ) * 1000 ) ;
# else
sleep ( static_cast < unsigned int > ( time ) ) ;
# endif
LogMessage ( logger , log_message . c_str ( ) ) ;
LogMessage ( logger , log_message . c_str ( ) ) ;
// At this time, the new log file should be created.
// At this time, the new log file should be created.
GetFileCreateTime ( kLogFile , & actual_create_time ) ;
actual_ctime = logger - > TEST_ctime ( ) ;
EXPECT_GT ( actual_create_time , expected_create_ time ) ;
EXPECT_LT ( expected_ctime , actual_c time ) ;
EXPECT_LT ( logger - > GetLogFileSize ( ) , total_log_size ) ;
EXPECT_LT ( logger - > GetLogFileSize ( ) , total_log_size ) ;
expected_create_time = actual_create_time ;
return expected_create_time ;
}
}
TEST_F ( AutoRollLoggerTest , RollLogFileBySize ) {
TEST_F ( AutoRollLoggerTest , RollLogFileBySize ) {
@ -163,16 +167,19 @@ TEST_F(AutoRollLoggerTest, RollLogFileBySize) {
}
}
TEST_F ( AutoRollLoggerTest , RollLogFileByTime ) {
TEST_F ( AutoRollLoggerTest , RollLogFileByTime ) {
size_t time = 2 ;
NoSleepEnv nse ( Env : : Default ( ) ) ;
size_t log_size = 1024 * 5 ;
InitTestDb ( ) ;
size_t time = 2 ;
// -- Test the existence of file during the server restart.
size_t log_size = 1024 * 5 ;
ASSERT_EQ ( Status : : NotFound ( ) , env - > FileExists ( kLogFile ) ) ;
AutoRollLogger logger ( Env : : Default ( ) , kTestDir , " " , log_size , time ) ;
InitTestDb ( ) ;
ASSERT_OK ( env - > FileExists ( kLogFile ) ) ;
// -- Test the existence of file during the server restart.
ASSERT_EQ ( Status : : NotFound ( ) , default_env - > FileExists ( kLogFile ) ) ;
AutoRollLogger logger ( & nse , kTestDir , " " , log_size , time ) ;
ASSERT_OK ( default_env - > FileExists ( kLogFile ) ) ;
RollLogFileByTimeTest ( & logger , time , kSampleMessage + " :RollLogFileByTime " ) ;
RollLogFileByTimeTest ( & nse , & logger , time ,
kSampleMessage + " :RollLogFileByTime " ) ;
}
}
TEST_F ( AutoRollLoggerTest , OpenLogFilesMultipleTimesWithOptionLog_max_size ) {
TEST_F ( AutoRollLoggerTest , OpenLogFilesMultipleTimesWithOptionLog_max_size ) {
@ -205,16 +212,16 @@ TEST_F(AutoRollLoggerTest, CompositeRollByTimeAndSizeLogger) {
InitTestDb ( ) ;
InitTestDb ( ) ;
AutoRollLogger logger ( Env : : Default ( ) , kTestDir , " " , log_max_size , time ) ;
NoSleepEnv nse ( Env : : Default ( ) ) ;
AutoRollLogger logger ( & nse , kTestDir , " " , log_max_size , time ) ;
// Test the ability to roll by size
// Test the ability to roll by size
RollLogFileBySizeTest (
RollLogFileBySizeTest ( & logger , log_max_size ,
& logger , log_max_size ,
kSampleMessage + " :CompositeRollByTimeAndSizeLogger " ) ;
kSampleMessage + " :CompositeRollByTimeAndSizeLogger " ) ;
// Test the ability to roll by Time
// Test the ability to roll by Time
RollLogFileByTimeTest ( & logger , time ,
RollLogFileByTimeTest ( & nse , & logger , time ,
kSampleMessage + " :CompositeRollByTimeAndSizeLogger " ) ;
kSampleMessage + " :CompositeRollByTimeAndSizeLogger " ) ;
}
}
# ifndef OS_WIN
# ifndef OS_WIN
@ -222,6 +229,7 @@ TEST_F(AutoRollLoggerTest, CompositeRollByTimeAndSizeLogger) {
// port
// port
TEST_F ( AutoRollLoggerTest , CreateLoggerFromOptions ) {
TEST_F ( AutoRollLoggerTest , CreateLoggerFromOptions ) {
DBOptions options ;
DBOptions options ;
NoSleepEnv nse ( Env : : Default ( ) ) ;
shared_ptr < Logger > logger ;
shared_ptr < Logger > logger ;
// Normal logger
// Normal logger
@ -240,15 +248,15 @@ TEST_F(AutoRollLoggerTest, CreateLoggerFromOptions) {
kSampleMessage + " :CreateLoggerFromOptions - size " ) ;
kSampleMessage + " :CreateLoggerFromOptions - size " ) ;
// Only roll by Time
// Only roll by Time
options . env = & nse ;
InitTestDb ( ) ;
InitTestDb ( ) ;
options . max_log_file_size = 0 ;
options . max_log_file_size = 0 ;
options . log_file_time_to_roll = 2 ;
options . log_file_time_to_roll = 2 ;
ASSERT_OK ( CreateLoggerFromOptions ( kTestDir , options , & logger ) ) ;
ASSERT_OK ( CreateLoggerFromOptions ( kTestDir , options , & logger ) ) ;
auto_roll_logger =
auto_roll_logger =
dynamic_cast < AutoRollLogger * > ( logger . get ( ) ) ;
dynamic_cast < AutoRollLogger * > ( logger . get ( ) ) ;
RollLogFileByTimeTest (
RollLogFileByTimeTest ( & nse , auto_roll_logger , options . log_file_time_to_roll ,
auto_roll_logger , options . log_file_time_to_roll ,
kSampleMessage + " :CreateLoggerFromOptions - time " ) ;
kSampleMessage + " :CreateLoggerFromOptions - time " ) ;
// roll by both Time and size
// roll by both Time and size
InitTestDb ( ) ;
InitTestDb ( ) ;
@ -257,12 +265,10 @@ TEST_F(AutoRollLoggerTest, CreateLoggerFromOptions) {
ASSERT_OK ( CreateLoggerFromOptions ( kTestDir , options , & logger ) ) ;
ASSERT_OK ( CreateLoggerFromOptions ( kTestDir , options , & logger ) ) ;
auto_roll_logger =
auto_roll_logger =
dynamic_cast < AutoRollLogger * > ( logger . get ( ) ) ;
dynamic_cast < AutoRollLogger * > ( logger . get ( ) ) ;
RollLogFileBySizeTest (
RollLogFileBySizeTest ( auto_roll_logger , options . max_log_file_size ,
auto_roll_logger , options . max_log_file_size ,
kSampleMessage + " :CreateLoggerFromOptions - both " ) ;
kSampleMessage + " :CreateLoggerFromOptions - both " ) ;
RollLogFileByTimeTest ( & nse , auto_roll_logger , options . log_file_time_to_roll ,
RollLogFileByTimeTest (
kSampleMessage + " :CreateLoggerFromOptions - both " ) ;
auto_roll_logger , options . log_file_time_to_roll ,
kSampleMessage + " :CreateLoggerFromOptions - both " ) ;
}
}
TEST_F ( AutoRollLoggerTest , LogFlushWhileRolling ) {
TEST_F ( AutoRollLoggerTest , LogFlushWhileRolling ) {
@ -462,7 +468,7 @@ TEST_F(AutoRollLoggerTest, LogFileExistence) {
options . max_log_file_size = 100 * 1024 * 1024 ;
options . max_log_file_size = 100 * 1024 * 1024 ;
options . create_if_missing = true ;
options . create_if_missing = true ;
ASSERT_OK ( rocksdb : : DB : : Open ( options , kTestDir , & db ) ) ;
ASSERT_OK ( rocksdb : : DB : : Open ( options , kTestDir , & db ) ) ;
ASSERT_OK ( env - > FileExists ( kLogFile ) ) ;
ASSERT_OK ( default_ env- > FileExists ( kLogFile ) ) ;
delete db ;
delete db ;
}
}