Add test function MockTimeEnv.SleepForMicroseconds() (#7293)
Summary: And change the internal time value from seconds to microseconds. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7293 Reviewed By: pdillinger Differential Revision: D23253751 Pulled By: jay-zhuang fbshipit-source-id: 36aa9376b8801b85bd10163173590a17cf4f3a3a
This commit is contained in:
parent
a1b5484811
commit
187964a039
@ -38,8 +38,6 @@ TEST_F(StatsDumpSchedulerTest, Basic) {
|
|||||||
options.stats_dump_period_sec = kPeriodSec;
|
options.stats_dump_period_sec = kPeriodSec;
|
||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
|
|
||||||
int dump_st_counter = 0;
|
int dump_st_counter = 0;
|
||||||
@ -56,9 +54,8 @@ TEST_F(StatsDumpSchedulerTest, Basic) {
|
|||||||
ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_dump_period_sec);
|
ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_dump_period_sec);
|
||||||
ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_persist_period_sec);
|
ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_persist_period_sec);
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
auto scheduler = dbfull()->TEST_GetStatsDumpScheduler();
|
auto scheduler = dbfull()->TEST_GetStatsDumpScheduler();
|
||||||
ASSERT_NE(nullptr, scheduler);
|
ASSERT_NE(nullptr, scheduler);
|
||||||
@ -67,16 +64,14 @@ TEST_F(StatsDumpSchedulerTest, Basic) {
|
|||||||
ASSERT_EQ(1, dump_st_counter);
|
ASSERT_EQ(1, dump_st_counter);
|
||||||
ASSERT_EQ(1, pst_st_counter);
|
ASSERT_EQ(1, pst_st_counter);
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
|
|
||||||
ASSERT_EQ(2, dump_st_counter);
|
ASSERT_EQ(2, dump_st_counter);
|
||||||
ASSERT_EQ(2, pst_st_counter);
|
ASSERT_EQ(2, pst_st_counter);
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
|
|
||||||
ASSERT_EQ(3, dump_st_counter);
|
ASSERT_EQ(3, dump_st_counter);
|
||||||
ASSERT_EQ(3, pst_st_counter);
|
ASSERT_EQ(3, pst_st_counter);
|
||||||
@ -100,9 +95,8 @@ TEST_F(StatsDumpSchedulerTest, Basic) {
|
|||||||
ASSERT_EQ(1, scheduler->TEST_GetValidTaskNum());
|
ASSERT_EQ(1, scheduler->TEST_GetValidTaskNum());
|
||||||
|
|
||||||
dump_st_counter = 0;
|
dump_st_counter = 0;
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_EQ(1, dump_st_counter);
|
ASSERT_EQ(1, dump_st_counter);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
@ -117,8 +111,6 @@ TEST_F(StatsDumpSchedulerTest, MultiInstances) {
|
|||||||
options.stats_dump_period_sec = kPeriodSec;
|
options.stats_dump_period_sec = kPeriodSec;
|
||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
|
|
||||||
int dump_st_counter = 0;
|
int dump_st_counter = 0;
|
||||||
@ -141,23 +133,20 @@ TEST_F(StatsDumpSchedulerTest, MultiInstances) {
|
|||||||
ASSERT_EQ(kInstanceNum * 2, scheduler->TEST_GetValidTaskNum());
|
ASSERT_EQ(kInstanceNum * 2, scheduler->TEST_GetValidTaskNum());
|
||||||
|
|
||||||
int expected_run = kInstanceNum;
|
int expected_run = kInstanceNum;
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbi->TEST_WaitForStatsDumpRun(
|
dbi->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
ASSERT_EQ(expected_run, dump_st_counter);
|
ASSERT_EQ(expected_run, dump_st_counter);
|
||||||
ASSERT_EQ(expected_run, pst_st_counter);
|
ASSERT_EQ(expected_run, pst_st_counter);
|
||||||
|
|
||||||
expected_run += kInstanceNum;
|
expected_run += kInstanceNum;
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbi->TEST_WaitForStatsDumpRun(
|
dbi->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_EQ(expected_run, dump_st_counter);
|
ASSERT_EQ(expected_run, dump_st_counter);
|
||||||
ASSERT_EQ(expected_run, pst_st_counter);
|
ASSERT_EQ(expected_run, pst_st_counter);
|
||||||
|
|
||||||
expected_run += kInstanceNum;
|
expected_run += kInstanceNum;
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbi->TEST_WaitForStatsDumpRun(
|
dbi->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_EQ(expected_run, dump_st_counter);
|
ASSERT_EQ(expected_run, dump_st_counter);
|
||||||
ASSERT_EQ(expected_run, pst_st_counter);
|
ASSERT_EQ(expected_run, pst_st_counter);
|
||||||
|
|
||||||
@ -168,12 +157,10 @@ TEST_F(StatsDumpSchedulerTest, MultiInstances) {
|
|||||||
|
|
||||||
expected_run += (kInstanceNum - half) * 2;
|
expected_run += (kInstanceNum - half) * 2;
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbi->TEST_WaitForStatsDumpRun(
|
dbi->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbi->TEST_WaitForStatsDumpRun(
|
dbi->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_EQ(expected_run, dump_st_counter);
|
ASSERT_EQ(expected_run, dump_st_counter);
|
||||||
ASSERT_EQ(expected_run, pst_st_counter);
|
ASSERT_EQ(expected_run, pst_st_counter);
|
||||||
|
|
||||||
@ -191,7 +178,6 @@ TEST_F(StatsDumpSchedulerTest, MultiEnv) {
|
|||||||
options1.stats_dump_period_sec = kDumpPeriodSec;
|
options1.stats_dump_period_sec = kDumpPeriodSec;
|
||||||
options1.stats_persist_period_sec = kPersistPeriodSec;
|
options1.stats_persist_period_sec = kPersistPeriodSec;
|
||||||
options1.create_if_missing = true;
|
options1.create_if_missing = true;
|
||||||
mock_env_->set_current_time(0);
|
|
||||||
options1.env = mock_env_.get();
|
options1.env = mock_env_.get();
|
||||||
|
|
||||||
Reopen(options1);
|
Reopen(options1);
|
||||||
@ -201,7 +187,6 @@ TEST_F(StatsDumpSchedulerTest, MultiEnv) {
|
|||||||
options2.stats_dump_period_sec = kDumpPeriodSec;
|
options2.stats_dump_period_sec = kDumpPeriodSec;
|
||||||
options2.stats_persist_period_sec = kPersistPeriodSec;
|
options2.stats_persist_period_sec = kPersistPeriodSec;
|
||||||
options2.create_if_missing = true;
|
options2.create_if_missing = true;
|
||||||
mock_env2->set_current_time(0);
|
|
||||||
options1.env = mock_env2.get();
|
options1.env = mock_env2.get();
|
||||||
|
|
||||||
std::string dbname = test::PerThreadDBPath("multi_env_test");
|
std::string dbname = test::PerThreadDBPath("multi_env_test");
|
||||||
|
@ -55,8 +55,6 @@ TEST_F(StatsHistoryTest, RunStatsDumpPeriodSec) {
|
|||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
options.stats_dump_period_sec = kPeriodSec;
|
options.stats_dump_period_sec = kPeriodSec;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
SyncPoint::GetInstance()->SetCallBack("DBImpl::DumpStats:1",
|
SyncPoint::GetInstance()->SetCallBack("DBImpl::DumpStats:1",
|
||||||
@ -66,20 +64,18 @@ TEST_F(StatsHistoryTest, RunStatsDumpPeriodSec) {
|
|||||||
|
|
||||||
// Wait for the first stats persist to finish, as the initial delay could be
|
// Wait for the first stats persist to finish, as the initial delay could be
|
||||||
// different.
|
// different.
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_GE(counter, 1);
|
ASSERT_GE(counter, 1);
|
||||||
|
|
||||||
// Test cancel job through SetOptions
|
// Test cancel job through SetOptions
|
||||||
ASSERT_OK(dbfull()->SetDBOptions({{"stats_dump_period_sec", "0"}}));
|
ASSERT_OK(dbfull()->SetDBOptions({{"stats_dump_period_sec", "0"}}));
|
||||||
int old_val = counter;
|
int old_val = counter;
|
||||||
for (int i = 1; i < 20; ++i) {
|
for (int i = 1; i < 20; ++i) {
|
||||||
mock_env_->set_current_time(i + mock_time_sec);
|
mock_env_->MockSleepForSeconds(kPeriodSec);
|
||||||
}
|
}
|
||||||
ASSERT_EQ(counter, old_val);
|
ASSERT_EQ(counter, old_val);
|
||||||
Close();
|
Close();
|
||||||
@ -91,8 +87,6 @@ TEST_F(StatsHistoryTest, StatsPersistScheduling) {
|
|||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
SyncPoint::GetInstance()->SetCallBack("DBImpl::PersistStats:Entry",
|
SyncPoint::GetInstance()->SetCallBack("DBImpl::PersistStats:Entry",
|
||||||
@ -102,21 +96,18 @@ TEST_F(StatsHistoryTest, StatsPersistScheduling) {
|
|||||||
|
|
||||||
// Wait for the first stats persist to finish, as the initial delay could be
|
// Wait for the first stats persist to finish, as the initial delay could be
|
||||||
// different.
|
// different.
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_GE(counter, 1);
|
ASSERT_GE(counter, 1);
|
||||||
|
|
||||||
// Test cacel job through SetOptions
|
// Test cancel job through SetOptions
|
||||||
ASSERT_OK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "0"}}));
|
ASSERT_OK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "0"}}));
|
||||||
int old_val = counter;
|
int old_val = counter;
|
||||||
mock_time_sec += kPeriodSec * 2;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec * 2); });
|
||||||
ASSERT_EQ(counter, old_val);
|
ASSERT_EQ(counter, old_val);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
@ -124,19 +115,21 @@ TEST_F(StatsHistoryTest, StatsPersistScheduling) {
|
|||||||
|
|
||||||
// Test enabling persistent stats for the first time
|
// Test enabling persistent stats for the first time
|
||||||
TEST_F(StatsHistoryTest, PersistentStatsFreshInstall) {
|
TEST_F(StatsHistoryTest, PersistentStatsFreshInstall) {
|
||||||
|
constexpr unsigned int kPeriodSec = 5;
|
||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
options.stats_persist_period_sec = 0;
|
options.stats_persist_period_sec = 0;
|
||||||
mock_env_->set_current_time(0); // in seconds
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
SyncPoint::GetInstance()->SetCallBack("DBImpl::PersistStats:Entry",
|
SyncPoint::GetInstance()->SetCallBack("DBImpl::PersistStats:Entry",
|
||||||
[&](void* /*arg*/) { counter++; });
|
[&](void* /*arg*/) { counter++; });
|
||||||
Reopen(options);
|
Reopen(options);
|
||||||
ASSERT_OK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "5"}}));
|
ASSERT_OK(dbfull()->SetDBOptions(
|
||||||
ASSERT_EQ(5u, dbfull()->GetDBOptions().stats_persist_period_sec);
|
{{"stats_persist_period_sec", std::to_string(kPeriodSec)}}));
|
||||||
|
ASSERT_EQ(kPeriodSec, dbfull()->GetDBOptions().stats_persist_period_sec);
|
||||||
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun([&] { mock_env_->set_current_time(5); });
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
ASSERT_GE(counter, 1);
|
ASSERT_GE(counter, 1);
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
@ -148,41 +141,37 @@ TEST_F(StatsHistoryTest, GetStatsHistoryInMemory) {
|
|||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
CreateColumnFamilies({"pikachu"}, options);
|
CreateColumnFamilies({"pikachu"}, options);
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_OK(Put("foo", "bar"));
|
||||||
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
||||||
|
|
||||||
// make sure the first stats persist to finish
|
// make sure the first stats persist to finish
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
// Wait for stats persist to finish
|
// Wait for stats persist to finish
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
|
|
||||||
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
||||||
db_->GetStatsHistory(0, mock_time_sec + 1, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
// disabled stats snapshots
|
// disabled stats snapshots
|
||||||
ASSERT_OK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "0"}}));
|
ASSERT_OK(dbfull()->SetDBOptions({{"stats_persist_period_sec", "0"}}));
|
||||||
size_t stats_count = 0;
|
size_t stats_count = 0;
|
||||||
for (; stats_iter->Valid(); stats_iter->Next()) {
|
for (; stats_iter->Valid(); stats_iter->Next()) {
|
||||||
auto stats_map = stats_iter->GetStatsMap();
|
auto stats_map = stats_iter->GetStatsMap();
|
||||||
ASSERT_EQ(stats_iter->GetStatsTime(), mock_time_sec);
|
ASSERT_EQ(stats_iter->GetStatsTime(), mock_env_->NowSeconds());
|
||||||
stats_count += stats_map.size();
|
stats_count += stats_map.size();
|
||||||
}
|
}
|
||||||
ASSERT_GT(stats_count, 0);
|
ASSERT_GT(stats_count, 0);
|
||||||
// Wait a bit and verify no more stats are found
|
// Wait a bit and verify no more stats are found
|
||||||
for (; mock_time_sec < 30; ++mock_time_sec) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(1); });
|
||||||
}
|
}
|
||||||
db_->GetStatsHistory(0, mock_time_sec, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds(), &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
size_t stats_count_new = 0;
|
size_t stats_count_new = 0;
|
||||||
for (; stats_iter->Valid(); stats_iter->Next()) {
|
for (; stats_iter->Valid(); stats_iter->Next()) {
|
||||||
@ -198,8 +187,6 @@ TEST_F(StatsHistoryTest, InMemoryStatsHistoryPurging) {
|
|||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
|
|
||||||
CreateColumnFamilies({"pikachu"}, options);
|
CreateColumnFamilies({"pikachu"}, options);
|
||||||
@ -221,11 +208,6 @@ TEST_F(StatsHistoryTest, InMemoryStatsHistoryPurging) {
|
|||||||
ASSERT_OK(Flush());
|
ASSERT_OK(Flush());
|
||||||
ASSERT_OK(Delete("sol"));
|
ASSERT_OK(Delete("sol"));
|
||||||
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr);
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr);
|
||||||
// Wait for stats persist to finish
|
|
||||||
for (mock_time_sec = 1; mock_time_sec < kPeriodSec; mock_time_sec++) {
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
|
||||||
}
|
|
||||||
|
|
||||||
// second round of ops
|
// second round of ops
|
||||||
ASSERT_OK(Put("saigon", "saigon"));
|
ASSERT_OK(Put("saigon", "saigon"));
|
||||||
@ -239,13 +221,14 @@ TEST_F(StatsHistoryTest, InMemoryStatsHistoryPurging) {
|
|||||||
ASSERT_OK(Flush());
|
ASSERT_OK(Flush());
|
||||||
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr);
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr);
|
||||||
|
|
||||||
for (; mock_time_sec < 10; mock_time_sec++) {
|
const int kIterations = 10;
|
||||||
|
for (int i = 0; i < kIterations; ++i) {
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
||||||
db_->GetStatsHistory(0, 10, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
size_t stats_count = 0;
|
size_t stats_count = 0;
|
||||||
int slice_count = 0;
|
int slice_count = 0;
|
||||||
@ -255,19 +238,19 @@ TEST_F(StatsHistoryTest, InMemoryStatsHistoryPurging) {
|
|||||||
stats_count += stats_map.size();
|
stats_count += stats_map.size();
|
||||||
}
|
}
|
||||||
size_t stats_history_size = dbfull()->TEST_EstimateInMemoryStatsHistorySize();
|
size_t stats_history_size = dbfull()->TEST_EstimateInMemoryStatsHistorySize();
|
||||||
ASSERT_GE(slice_count, 9);
|
ASSERT_GE(slice_count, kIterations - 1);
|
||||||
ASSERT_GE(stats_history_size, 13000);
|
ASSERT_GE(stats_history_size, 13000);
|
||||||
// capping memory cost at 13000 bytes since one slice is around 10000~13000
|
// capping memory cost at 13000 bytes since one slice is around 10000~13000
|
||||||
ASSERT_OK(dbfull()->SetDBOptions({{"stats_history_buffer_size", "13000"}}));
|
ASSERT_OK(dbfull()->SetDBOptions({{"stats_history_buffer_size", "13000"}}));
|
||||||
ASSERT_EQ(13000, dbfull()->GetDBOptions().stats_history_buffer_size);
|
ASSERT_EQ(13000, dbfull()->GetDBOptions().stats_history_buffer_size);
|
||||||
|
|
||||||
// Wait for stats persist to finish
|
// Wait for stats persist to finish
|
||||||
for (; mock_time_sec < 20; mock_time_sec++) {
|
for (int i = 0; i < kIterations; ++i) {
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
}
|
}
|
||||||
|
|
||||||
db_->GetStatsHistory(0, 20, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
size_t stats_count_reopen = 0;
|
size_t stats_count_reopen = 0;
|
||||||
slice_count = 0;
|
slice_count = 0;
|
||||||
@ -303,8 +286,6 @@ TEST_F(StatsHistoryTest, GetStatsHistoryFromDisk) {
|
|||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
options.persist_stats_to_disk = true;
|
options.persist_stats_to_disk = true;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
CreateColumnFamilies({"pikachu"}, options);
|
CreateColumnFamilies({"pikachu"}, options);
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_OK(Put("foo", "bar"));
|
||||||
@ -313,31 +294,27 @@ TEST_F(StatsHistoryTest, GetStatsHistoryFromDisk) {
|
|||||||
|
|
||||||
// Wait for the first stats persist to finish, as the initial delay could be
|
// Wait for the first stats persist to finish, as the initial delay could be
|
||||||
// different.
|
// different.
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
// Wait for stats persist to finish
|
// Wait for stats persist to finish
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
|
|
||||||
auto iter =
|
auto iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
int key_count1 = countkeys(iter);
|
int key_count1 = countkeys(iter);
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
iter =
|
iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
int key_count2 = countkeys(iter);
|
int key_count2 = countkeys(iter);
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
iter =
|
iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
int key_count3 = countkeys(iter);
|
int key_count3 = countkeys(iter);
|
||||||
@ -346,7 +323,7 @@ TEST_F(StatsHistoryTest, GetStatsHistoryFromDisk) {
|
|||||||
ASSERT_GE(key_count3, key_count2);
|
ASSERT_GE(key_count3, key_count2);
|
||||||
ASSERT_EQ(key_count3 - key_count2, key_count2 - key_count1);
|
ASSERT_EQ(key_count3 - key_count2, key_count2 - key_count1);
|
||||||
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
||||||
db_->GetStatsHistory(0, mock_time_sec + 1, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
size_t stats_count = 0;
|
size_t stats_count = 0;
|
||||||
int slice_count = 0;
|
int slice_count = 0;
|
||||||
@ -367,7 +344,7 @@ TEST_F(StatsHistoryTest, GetStatsHistoryFromDisk) {
|
|||||||
ASSERT_EQ(stats_count, key_count3 - 2);
|
ASSERT_EQ(stats_count, key_count3 - 2);
|
||||||
// verify reopen will not cause data loss
|
// verify reopen will not cause data loss
|
||||||
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
||||||
db_->GetStatsHistory(0, mock_time_sec + 1, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
size_t stats_count_reopen = 0;
|
size_t stats_count_reopen = 0;
|
||||||
int slice_count_reopen = 0;
|
int slice_count_reopen = 0;
|
||||||
@ -398,11 +375,8 @@ TEST_F(StatsHistoryTest, PersitentStatsVerifyValue) {
|
|||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
options.persist_stats_to_disk = true;
|
options.persist_stats_to_disk = true;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
std::map<std::string, uint64_t> stats_map_before;
|
std::map<std::string, uint64_t> stats_map_before;
|
||||||
ASSERT_TRUE(options.statistics->getTickerMap(&stats_map_before));
|
ASSERT_TRUE(options.statistics->getTickerMap(&stats_map_before));
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
CreateColumnFamilies({"pikachu"}, options);
|
CreateColumnFamilies({"pikachu"}, options);
|
||||||
ASSERT_OK(Put("foo", "bar"));
|
ASSERT_OK(Put("foo", "bar"));
|
||||||
@ -411,43 +385,38 @@ TEST_F(StatsHistoryTest, PersitentStatsVerifyValue) {
|
|||||||
|
|
||||||
// Wait for the first stats persist to finish, as the initial delay could be
|
// Wait for the first stats persist to finish, as the initial delay could be
|
||||||
// different.
|
// different.
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
// Wait for stats persist to finish
|
// Wait for stats persist to finish
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
auto iter =
|
auto iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
countkeys(iter);
|
countkeys(iter);
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
iter =
|
iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
countkeys(iter);
|
countkeys(iter);
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
iter =
|
iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
countkeys(iter);
|
countkeys(iter);
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
|
|
||||||
std::map<std::string, uint64_t> stats_map_after;
|
std::map<std::string, uint64_t> stats_map_after;
|
||||||
ASSERT_TRUE(options.statistics->getTickerMap(&stats_map_after));
|
ASSERT_TRUE(options.statistics->getTickerMap(&stats_map_after));
|
||||||
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
||||||
db_->GetStatsHistory(0, mock_time_sec + 1, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
std::string sample = "rocksdb.num.iterator.deleted";
|
std::string sample = "rocksdb.num.iterator.deleted";
|
||||||
uint64_t recovered_value = 0;
|
uint64_t recovered_value = 0;
|
||||||
@ -464,7 +433,7 @@ TEST_F(StatsHistoryTest, PersitentStatsVerifyValue) {
|
|||||||
|
|
||||||
// test stats value retains after recovery
|
// test stats value retains after recovery
|
||||||
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
||||||
db_->GetStatsHistory(0, mock_time_sec + 1, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds() + 1, &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
uint64_t new_recovered_value = 0;
|
uint64_t new_recovered_value = 0;
|
||||||
for (int i = 2; stats_iter->Valid(); stats_iter->Next(), i++) {
|
for (int i = 2; stats_iter->Valid(); stats_iter->Next(), i++) {
|
||||||
@ -492,8 +461,6 @@ TEST_F(StatsHistoryTest, PersistentStatsCreateColumnFamilies) {
|
|||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
options.persist_stats_to_disk = true;
|
options.persist_stats_to_disk = true;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
ASSERT_OK(TryReopen(options));
|
ASSERT_OK(TryReopen(options));
|
||||||
CreateColumnFamilies({"one", "two", "three"}, options);
|
CreateColumnFamilies({"one", "two", "three"}, options);
|
||||||
@ -505,13 +472,11 @@ TEST_F(StatsHistoryTest, PersistentStatsCreateColumnFamilies) {
|
|||||||
ASSERT_EQ(Get(2, "foo"), "bar");
|
ASSERT_EQ(Get(2, "foo"), "bar");
|
||||||
|
|
||||||
// make sure the first stats persist to finish
|
// make sure the first stats persist to finish
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
auto iter =
|
auto iter =
|
||||||
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
db_->NewIterator(ReadOptions(), dbfull()->PersistentStatsColumnFamily());
|
||||||
int key_count = countkeys(iter);
|
int key_count = countkeys(iter);
|
||||||
@ -520,7 +485,7 @@ TEST_F(StatsHistoryTest, PersistentStatsCreateColumnFamilies) {
|
|||||||
uint64_t num_write_wal = 0;
|
uint64_t num_write_wal = 0;
|
||||||
std::string sample = "rocksdb.write.wal";
|
std::string sample = "rocksdb.write.wal";
|
||||||
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
std::unique_ptr<StatsHistoryIterator> stats_iter;
|
||||||
db_->GetStatsHistory(0, mock_time_sec, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds(), &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
for (; stats_iter->Valid(); stats_iter->Next()) {
|
for (; stats_iter->Valid(); stats_iter->Next()) {
|
||||||
auto stats_map = stats_iter->GetStatsMap();
|
auto stats_map = stats_iter->GetStatsMap();
|
||||||
@ -556,7 +521,7 @@ TEST_F(StatsHistoryTest, PersistentStatsCreateColumnFamilies) {
|
|||||||
ASSERT_NOK(db_->CreateColumnFamily(cf_opts, kPersistentStatsColumnFamilyName,
|
ASSERT_NOK(db_->CreateColumnFamily(cf_opts, kPersistentStatsColumnFamilyName,
|
||||||
&handle));
|
&handle));
|
||||||
// verify stats is not affected by prior failed CF creation
|
// verify stats is not affected by prior failed CF creation
|
||||||
db_->GetStatsHistory(0, mock_time_sec, &stats_iter);
|
db_->GetStatsHistory(0, mock_env_->NowSeconds(), &stats_iter);
|
||||||
ASSERT_TRUE(stats_iter != nullptr);
|
ASSERT_TRUE(stats_iter != nullptr);
|
||||||
num_write_wal = 0;
|
num_write_wal = 0;
|
||||||
for (; stats_iter->Valid(); stats_iter->Next()) {
|
for (; stats_iter->Valid(); stats_iter->Next()) {
|
||||||
@ -601,17 +566,14 @@ TEST_F(StatsHistoryTest, ForceManualFlushStatsCF) {
|
|||||||
options.stats_persist_period_sec = kPeriodSec;
|
options.stats_persist_period_sec = kPeriodSec;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
options.persist_stats_to_disk = true;
|
options.persist_stats_to_disk = true;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
options.env = mock_env_.get();
|
options.env = mock_env_.get();
|
||||||
CreateColumnFamilies({"pikachu"}, options);
|
CreateColumnFamilies({"pikachu"}, options);
|
||||||
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
ReopenWithColumnFamilies({"default", "pikachu"}, options);
|
||||||
|
|
||||||
// Wait for the first stats persist to finish, as the initial delay could be
|
// Wait for the first stats persist to finish, as the initial delay could be
|
||||||
// different.
|
// different.
|
||||||
mock_time_sec += kPeriodSec - 1;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec - 1); });
|
||||||
|
|
||||||
ColumnFamilyData* cfd_default =
|
ColumnFamilyData* cfd_default =
|
||||||
static_cast<ColumnFamilyHandleImpl*>(dbfull()->DefaultColumnFamily())
|
static_cast<ColumnFamilyHandleImpl*>(dbfull()->DefaultColumnFamily())
|
||||||
@ -629,9 +591,8 @@ TEST_F(StatsHistoryTest, ForceManualFlushStatsCF) {
|
|||||||
ASSERT_OK(Put(1, "Eevee", "v0"));
|
ASSERT_OK(Put(1, "Eevee", "v0"));
|
||||||
ASSERT_EQ("v0", Get(1, "Eevee"));
|
ASSERT_EQ("v0", Get(1, "Eevee"));
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
// writing to all three cf, flush default cf
|
// writing to all three cf, flush default cf
|
||||||
// LogNumbers: default: 14, stats: 4, pikachu: 4
|
// LogNumbers: default: 14, stats: 4, pikachu: 4
|
||||||
ASSERT_OK(Flush());
|
ASSERT_OK(Flush());
|
||||||
@ -655,9 +616,8 @@ TEST_F(StatsHistoryTest, ForceManualFlushStatsCF) {
|
|||||||
ASSERT_EQ("v2", Get("bar2"));
|
ASSERT_EQ("v2", Get("bar2"));
|
||||||
ASSERT_EQ("v2", Get("foo2"));
|
ASSERT_EQ("v2", Get("foo2"));
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
// writing to default and stats cf, flushing default cf
|
// writing to default and stats cf, flushing default cf
|
||||||
// LogNumbers: default: 19, stats: 19, pikachu: 19
|
// LogNumbers: default: 19, stats: 19, pikachu: 19
|
||||||
ASSERT_OK(Flush());
|
ASSERT_OK(Flush());
|
||||||
@ -671,9 +631,8 @@ TEST_F(StatsHistoryTest, ForceManualFlushStatsCF) {
|
|||||||
ASSERT_OK(Put(1, "Jolteon", "v3"));
|
ASSERT_OK(Put(1, "Jolteon", "v3"));
|
||||||
ASSERT_EQ("v3", Get(1, "Jolteon"));
|
ASSERT_EQ("v3", Get(1, "Jolteon"));
|
||||||
|
|
||||||
mock_time_sec += kPeriodSec;
|
|
||||||
dbfull()->TEST_WaitForStatsDumpRun(
|
dbfull()->TEST_WaitForStatsDumpRun(
|
||||||
[&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForSeconds(kPeriodSec); });
|
||||||
// writing to all three cf, flushing test cf
|
// writing to all three cf, flushing test cf
|
||||||
// LogNumbers: default: 19, stats: 19, pikachu: 22
|
// LogNumbers: default: 19, stats: 19, pikachu: 22
|
||||||
ASSERT_OK(Flush(1));
|
ASSERT_OK(Flush(1));
|
||||||
|
@ -16,29 +16,47 @@ class MockTimeEnv : public EnvWrapper {
|
|||||||
public:
|
public:
|
||||||
explicit MockTimeEnv(Env* base) : EnvWrapper(base) {}
|
explicit MockTimeEnv(Env* base) : EnvWrapper(base) {}
|
||||||
|
|
||||||
virtual Status GetCurrentTime(int64_t* time) override {
|
virtual Status GetCurrentTime(int64_t* time_sec) override {
|
||||||
assert(time != nullptr);
|
assert(time_sec != nullptr);
|
||||||
assert(current_time_ <=
|
*time_sec = static_cast<int64_t>(current_time_us_ / kMicrosInSecond);
|
||||||
static_cast<uint64_t>(std::numeric_limits<int64_t>::max()));
|
|
||||||
*time = static_cast<int64_t>(current_time_);
|
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint64_t NowMicros() override {
|
virtual uint64_t NowSeconds() { return current_time_us_ / kMicrosInSecond; }
|
||||||
assert(current_time_ <= std::numeric_limits<uint64_t>::max() / 1000000);
|
|
||||||
return current_time_ * 1000000;
|
virtual uint64_t NowMicros() override { return current_time_us_; }
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint64_t NowNanos() override {
|
virtual uint64_t NowNanos() override {
|
||||||
assert(current_time_ <= std::numeric_limits<uint64_t>::max() / 1000000000);
|
assert(current_time_us_ <= std::numeric_limits<uint64_t>::max() / 1000);
|
||||||
return current_time_ * 1000000000;
|
return current_time_us_ * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RealNowMicros() { return target()->NowMicros(); }
|
uint64_t RealNowMicros() { return target()->NowMicros(); }
|
||||||
|
|
||||||
void set_current_time(uint64_t time) {
|
void set_current_time(uint64_t time_sec) {
|
||||||
assert(time >= current_time_);
|
assert(time_sec < std::numeric_limits<uint64_t>::max() / kMicrosInSecond);
|
||||||
current_time_ = time;
|
assert(time_sec * kMicrosInSecond >= current_time_us_);
|
||||||
|
current_time_us_ = time_sec * kMicrosInSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's a fake sleep that just updates the Env current time, which is similar
|
||||||
|
// to `NoSleepEnv.SleepForMicroseconds()` and
|
||||||
|
// `SpecialEnv.MockSleepForMicroseconds()`.
|
||||||
|
// It's also similar to `set_current_time()`, which takes an absolute time in
|
||||||
|
// seconds, vs. this one takes the sleep in microseconds.
|
||||||
|
// Note: Not thread safe.
|
||||||
|
void MockSleepForMicroseconds(int micros) {
|
||||||
|
assert(micros >= 0);
|
||||||
|
assert(current_time_us_ + static_cast<uint64_t>(micros) >=
|
||||||
|
current_time_us_);
|
||||||
|
current_time_us_.fetch_add(micros);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MockSleepForSeconds(int seconds) {
|
||||||
|
assert(seconds >= 0);
|
||||||
|
uint64_t micros = static_cast<uint64_t>(seconds) * kMicrosInSecond;
|
||||||
|
assert(current_time_us_ + micros >= current_time_us_);
|
||||||
|
current_time_us_.fetch_add(micros);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this is a workaround for the different behavior on different platform
|
// TODO: this is a workaround for the different behavior on different platform
|
||||||
@ -66,7 +84,7 @@ class MockTimeEnv : public EnvWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<uint64_t> current_time_{0};
|
std::atomic<uint64_t> current_time_us_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
@ -15,56 +15,54 @@ class TimerTest : public testing::Test {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<MockTimeEnv> mock_env_;
|
std::unique_ptr<MockTimeEnv> mock_env_;
|
||||||
const uint64_t kSecond = 1000000; // 1sec = 1000000us
|
|
||||||
|
|
||||||
void SetUp() override { mock_env_->InstallTimedWaitFixCallback(); }
|
void SetUp() override { mock_env_->InstallTimedWaitFixCallback(); }
|
||||||
|
|
||||||
|
const int kUsPerSec = 1000000;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TimerTest, SingleScheduleOnceTest) {
|
TEST_F(TimerTest, SingleScheduleOnce) {
|
||||||
const int kInitDelaySec = 1;
|
const int kInitDelayUs = 1 * kUsPerSec;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
timer.Add([&] { count++; }, "fn_sch_test", kInitDelaySec * kSecond, 0);
|
timer.Add([&] { count++; }, "fn_sch_test", kInitDelayUs, 0);
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
|
|
||||||
ASSERT_EQ(0, count);
|
ASSERT_EQ(0, count);
|
||||||
// Wait for execution to finish
|
// Wait for execution to finish
|
||||||
mock_time_sec += kInitDelaySec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kInitDelayUs); });
|
||||||
ASSERT_EQ(1, count);
|
ASSERT_EQ(1, count);
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Shutdown());
|
ASSERT_TRUE(timer.Shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, MultipleScheduleOnceTest) {
|
TEST_F(TimerTest, MultipleScheduleOnce) {
|
||||||
const int kInitDelay1Sec = 1;
|
const int kInitDelay1Us = 1 * kUsPerSec;
|
||||||
const int kInitDelay2Sec = 3;
|
const int kInitDelay2Us = 3 * kUsPerSec;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
int count1 = 0;
|
int count1 = 0;
|
||||||
timer.Add([&] { count1++; }, "fn_sch_test1", kInitDelay1Sec * kSecond, 0);
|
timer.Add([&] { count1++; }, "fn_sch_test1", kInitDelay1Us, 0);
|
||||||
|
|
||||||
int count2 = 0;
|
int count2 = 0;
|
||||||
timer.Add([&] { count2++; }, "fn_sch_test2", kInitDelay2Sec * kSecond, 0);
|
timer.Add([&] { count2++; }, "fn_sch_test2", kInitDelay2Us, 0);
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
ASSERT_EQ(0, count1);
|
ASSERT_EQ(0, count1);
|
||||||
ASSERT_EQ(0, count2);
|
ASSERT_EQ(0, count2);
|
||||||
|
|
||||||
mock_time_sec = kInitDelay1Sec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kInitDelay1Us); });
|
||||||
|
|
||||||
ASSERT_EQ(1, count1);
|
ASSERT_EQ(1, count1);
|
||||||
ASSERT_EQ(0, count2);
|
ASSERT_EQ(0, count2);
|
||||||
|
|
||||||
mock_time_sec = kInitDelay2Sec;
|
timer.TEST_WaitForRun([&] {
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
mock_env_->MockSleepForMicroseconds(kInitDelay2Us - kInitDelay1Us);
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_EQ(1, count1);
|
ASSERT_EQ(1, count1);
|
||||||
ASSERT_EQ(1, count2);
|
ASSERT_EQ(1, count2);
|
||||||
@ -72,70 +70,62 @@ TEST_F(TimerTest, MultipleScheduleOnceTest) {
|
|||||||
ASSERT_TRUE(timer.Shutdown());
|
ASSERT_TRUE(timer.Shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, SingleScheduleRepeatedlyTest) {
|
TEST_F(TimerTest, SingleScheduleRepeatedly) {
|
||||||
const int kIterations = 5;
|
const int kIterations = 5;
|
||||||
const int kInitDelaySec = 1;
|
const int kInitDelayUs = 1 * kUsPerSec;
|
||||||
const int kRepeatSec = 1;
|
const int kRepeatUs = 1 * kUsPerSec;
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
int count = 0;
|
int count = 0;
|
||||||
timer.Add([&] { count++; }, "fn_sch_test", kInitDelaySec * kSecond,
|
timer.Add([&] { count++; }, "fn_sch_test", kInitDelayUs, kRepeatUs);
|
||||||
kRepeatSec * kSecond);
|
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
ASSERT_EQ(0, count);
|
ASSERT_EQ(0, count);
|
||||||
|
|
||||||
mock_time_sec += kInitDelaySec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kInitDelayUs); });
|
||||||
|
|
||||||
ASSERT_EQ(1, count);
|
ASSERT_EQ(1, count);
|
||||||
|
|
||||||
// Wait for execution to finish
|
// Wait for execution to finish
|
||||||
for (int i = 1; i < kIterations; i++) {
|
for (int i = 1; i < kIterations; i++) {
|
||||||
mock_time_sec += kRepeatSec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kRepeatUs); });
|
||||||
}
|
}
|
||||||
ASSERT_EQ(kIterations, count);
|
ASSERT_EQ(kIterations, count);
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Shutdown());
|
ASSERT_TRUE(timer.Shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, MultipleScheduleRepeatedlyTest) {
|
TEST_F(TimerTest, MultipleScheduleRepeatedly) {
|
||||||
const int kInitDelay1Sec = 0;
|
|
||||||
const int kInitDelay2Sec = 1;
|
|
||||||
const int kInitDelay3Sec = 0;
|
|
||||||
const int kRepeatSec = 2;
|
|
||||||
const int kLargeRepeatSec = 100;
|
|
||||||
const int kIterations = 5;
|
const int kIterations = 5;
|
||||||
|
const int kInitDelay1Us = 0 * kUsPerSec;
|
||||||
|
const int kInitDelay2Us = 1 * kUsPerSec;
|
||||||
|
const int kInitDelay3Us = 0 * kUsPerSec;
|
||||||
|
const int kRepeatUs = 2 * kUsPerSec;
|
||||||
|
const int kLargeRepeatUs = 100 * kUsPerSec;
|
||||||
|
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
int count1 = 0;
|
int count1 = 0;
|
||||||
timer.Add([&] { count1++; }, "fn_sch_test1", kInitDelay1Sec * kSecond,
|
timer.Add([&] { count1++; }, "fn_sch_test1", kInitDelay1Us, kRepeatUs);
|
||||||
kRepeatSec * kSecond);
|
|
||||||
|
|
||||||
int count2 = 0;
|
int count2 = 0;
|
||||||
timer.Add([&] { count2++; }, "fn_sch_test2", kInitDelay2Sec * kSecond,
|
timer.Add([&] { count2++; }, "fn_sch_test2", kInitDelay2Us, kRepeatUs);
|
||||||
kRepeatSec * kSecond);
|
|
||||||
|
|
||||||
// Add a function with relatively large repeat interval
|
// Add a function with relatively large repeat interval
|
||||||
int count3 = 0;
|
int count3 = 0;
|
||||||
timer.Add([&] { count3++; }, "fn_sch_test3", kInitDelay3Sec * kSecond,
|
timer.Add([&] { count3++; }, "fn_sch_test3", kInitDelay3Us, kLargeRepeatUs);
|
||||||
kLargeRepeatSec * kSecond);
|
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
|
|
||||||
ASSERT_EQ(0, count2);
|
ASSERT_EQ(0, count2);
|
||||||
ASSERT_EQ(0, count3);
|
|
||||||
// Wait for execution to finish
|
// Wait for execution to finish
|
||||||
for (; count1 < kIterations; mock_time_sec++) {
|
for (int i = 1; i < kIterations * (kRepeatUs / kUsPerSec); i++) {
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
timer.TEST_WaitForRun(
|
||||||
ASSERT_EQ((mock_time_sec + 2) / kRepeatSec, count1);
|
[&] { mock_env_->MockSleepForMicroseconds(1 * kUsPerSec); });
|
||||||
ASSERT_EQ((mock_time_sec + 1) / kRepeatSec, count2);
|
ASSERT_EQ((i + 2) / (kRepeatUs / kUsPerSec), count1);
|
||||||
|
ASSERT_EQ((i + 1) / (kRepeatUs / kUsPerSec), count2);
|
||||||
|
|
||||||
// large interval function should only run once (the first one).
|
// large interval function should only run once (the first one).
|
||||||
ASSERT_EQ(1, count3);
|
ASSERT_EQ(1, count3);
|
||||||
@ -144,8 +134,8 @@ TEST_F(TimerTest, MultipleScheduleRepeatedlyTest) {
|
|||||||
timer.Cancel("fn_sch_test1");
|
timer.Cancel("fn_sch_test1");
|
||||||
|
|
||||||
// Wait for execution to finish
|
// Wait for execution to finish
|
||||||
mock_time_sec++;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(1 * kUsPerSec); });
|
||||||
ASSERT_EQ(kIterations, count1);
|
ASSERT_EQ(kIterations, count1);
|
||||||
ASSERT_EQ(kIterations, count2);
|
ASSERT_EQ(kIterations, count2);
|
||||||
ASSERT_EQ(1, count3);
|
ASSERT_EQ(1, count3);
|
||||||
@ -156,8 +146,10 @@ TEST_F(TimerTest, MultipleScheduleRepeatedlyTest) {
|
|||||||
ASSERT_EQ(kIterations, count2);
|
ASSERT_EQ(kIterations, count2);
|
||||||
|
|
||||||
// execute the long interval one
|
// execute the long interval one
|
||||||
mock_time_sec = kLargeRepeatSec;
|
timer.TEST_WaitForRun([&] {
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
mock_env_->MockSleepForMicroseconds(
|
||||||
|
kLargeRepeatUs - static_cast<int>(mock_env_->NowMicros()));
|
||||||
|
});
|
||||||
ASSERT_EQ(2, count3);
|
ASSERT_EQ(2, count3);
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Shutdown());
|
ASSERT_TRUE(timer.Shutdown());
|
||||||
@ -165,33 +157,30 @@ TEST_F(TimerTest, MultipleScheduleRepeatedlyTest) {
|
|||||||
|
|
||||||
TEST_F(TimerTest, AddAfterStartTest) {
|
TEST_F(TimerTest, AddAfterStartTest) {
|
||||||
const int kIterations = 5;
|
const int kIterations = 5;
|
||||||
const int kInitDelaySec = 1;
|
const int kInitDelayUs = 1 * kUsPerSec;
|
||||||
const int kRepeatSec = 1;
|
const int kRepeatUs = 1 * kUsPerSec;
|
||||||
|
|
||||||
// wait timer to run and then add a new job
|
// wait timer to run and then add a new job
|
||||||
SyncPoint::GetInstance()->LoadDependency(
|
SyncPoint::GetInstance()->LoadDependency(
|
||||||
{{"Timer::Run::Waiting", "TimerTest:AddAfterStartTest:1"}});
|
{{"Timer::Run::Waiting", "TimerTest:AddAfterStartTest:1"}});
|
||||||
SyncPoint::GetInstance()->EnableProcessing();
|
SyncPoint::GetInstance()->EnableProcessing();
|
||||||
|
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
|
|
||||||
TEST_SYNC_POINT("TimerTest:AddAfterStartTest:1");
|
TEST_SYNC_POINT("TimerTest:AddAfterStartTest:1");
|
||||||
int count = 0;
|
int count = 0;
|
||||||
timer.Add([&] { count++; }, "fn_sch_test", kInitDelaySec * kSecond,
|
timer.Add([&] { count++; }, "fn_sch_test", kInitDelayUs, kRepeatUs);
|
||||||
kRepeatSec * kSecond);
|
|
||||||
ASSERT_EQ(0, count);
|
ASSERT_EQ(0, count);
|
||||||
// Wait for execution to finish
|
// Wait for execution to finish
|
||||||
mock_time_sec += kInitDelaySec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kInitDelayUs); });
|
||||||
ASSERT_EQ(1, count);
|
ASSERT_EQ(1, count);
|
||||||
|
|
||||||
for (int i = 1; i < kIterations; i++) {
|
for (int i = 1; i < kIterations; i++) {
|
||||||
mock_time_sec += kRepeatSec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kRepeatUs); });
|
||||||
}
|
}
|
||||||
ASSERT_EQ(kIterations, count);
|
ASSERT_EQ(kIterations, count);
|
||||||
|
|
||||||
@ -199,8 +188,8 @@ TEST_F(TimerTest, AddAfterStartTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, CancelRunningTask) {
|
TEST_F(TimerTest, CancelRunningTask) {
|
||||||
|
const int kRepeatUs = 1 * kUsPerSec;
|
||||||
constexpr char kTestFuncName[] = "test_func";
|
constexpr char kTestFuncName[] = "test_func";
|
||||||
mock_env_->set_current_time(0);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
int* value = new int;
|
int* value = new int;
|
||||||
@ -219,7 +208,7 @@ TEST_F(TimerTest, CancelRunningTask) {
|
|||||||
TEST_SYNC_POINT("TimerTest::CancelRunningTask:test_func:0");
|
TEST_SYNC_POINT("TimerTest::CancelRunningTask:test_func:0");
|
||||||
TEST_SYNC_POINT("TimerTest::CancelRunningTask:test_func:1");
|
TEST_SYNC_POINT("TimerTest::CancelRunningTask:test_func:1");
|
||||||
},
|
},
|
||||||
kTestFuncName, 0, 1 * kSecond);
|
kTestFuncName, 0, kRepeatUs);
|
||||||
port::Thread control_thr([&]() {
|
port::Thread control_thr([&]() {
|
||||||
TEST_SYNC_POINT("TimerTest::CancelRunningTask:BeforeCancel");
|
TEST_SYNC_POINT("TimerTest::CancelRunningTask:BeforeCancel");
|
||||||
timer.Cancel(kTestFuncName);
|
timer.Cancel(kTestFuncName);
|
||||||
@ -228,15 +217,15 @@ TEST_F(TimerTest, CancelRunningTask) {
|
|||||||
delete value;
|
delete value;
|
||||||
value = nullptr;
|
value = nullptr;
|
||||||
});
|
});
|
||||||
mock_env_->set_current_time(1);
|
mock_env_->MockSleepForMicroseconds(kRepeatUs);
|
||||||
control_thr.join();
|
control_thr.join();
|
||||||
ASSERT_TRUE(timer.Shutdown());
|
ASSERT_TRUE(timer.Shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, ShutdownRunningTask) {
|
TEST_F(TimerTest, ShutdownRunningTask) {
|
||||||
|
const int kRepeatUs = 1 * kUsPerSec;
|
||||||
constexpr char kTestFunc1Name[] = "test_func1";
|
constexpr char kTestFunc1Name[] = "test_func1";
|
||||||
constexpr char kTestFunc2Name[] = "test_func2";
|
constexpr char kTestFunc2Name[] = "test_func2";
|
||||||
mock_env_->set_current_time(0);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
SyncPoint::GetInstance()->DisableProcessing();
|
SyncPoint::GetInstance()->DisableProcessing();
|
||||||
@ -258,56 +247,52 @@ TEST_F(TimerTest, ShutdownRunningTask) {
|
|||||||
*value = 1;
|
*value = 1;
|
||||||
TEST_SYNC_POINT("TimerTest::ShutdownRunningTest:test_func:1");
|
TEST_SYNC_POINT("TimerTest::ShutdownRunningTest:test_func:1");
|
||||||
},
|
},
|
||||||
kTestFunc1Name, 0, 1 * kSecond);
|
kTestFunc1Name, 0, kRepeatUs);
|
||||||
|
|
||||||
timer.Add([&]() { ++(*value); }, kTestFunc2Name, 0, 1 * kSecond);
|
timer.Add([&]() { ++(*value); }, kTestFunc2Name, 0, kRepeatUs);
|
||||||
|
|
||||||
port::Thread control_thr([&]() {
|
port::Thread control_thr([&]() {
|
||||||
TEST_SYNC_POINT("TimerTest::ShutdownRunningTest:BeforeShutdown");
|
TEST_SYNC_POINT("TimerTest::ShutdownRunningTest:BeforeShutdown");
|
||||||
timer.Shutdown();
|
timer.Shutdown();
|
||||||
});
|
});
|
||||||
mock_env_->set_current_time(1);
|
mock_env_->MockSleepForMicroseconds(kRepeatUs);
|
||||||
control_thr.join();
|
control_thr.join();
|
||||||
delete value;
|
delete value;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, AddSameFuncName) {
|
TEST_F(TimerTest, AddSameFuncName) {
|
||||||
const int kInitDelaySec = 1;
|
const int kInitDelayUs = 1 * kUsPerSec;
|
||||||
const int kRepeat1Sec = 5;
|
const int kRepeat1Us = 5 * kUsPerSec;
|
||||||
const int kRepeat2Sec = 4;
|
const int kRepeat2Us = 4 * kUsPerSec;
|
||||||
|
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
|
|
||||||
int func_counter1 = 0;
|
int func_counter1 = 0;
|
||||||
timer.Add([&] { func_counter1++; }, "duplicated_func",
|
timer.Add([&] { func_counter1++; }, "duplicated_func", kInitDelayUs,
|
||||||
kInitDelaySec * kSecond, kRepeat1Sec * kSecond);
|
kRepeat1Us);
|
||||||
|
|
||||||
int func2_counter = 0;
|
int func2_counter = 0;
|
||||||
timer.Add([&] { func2_counter++; }, "func2", kInitDelaySec * kSecond,
|
timer.Add([&] { func2_counter++; }, "func2", kInitDelayUs, kRepeat2Us);
|
||||||
kRepeat2Sec * kSecond);
|
|
||||||
|
|
||||||
// New function with the same name should override the existing one
|
// New function with the same name should override the existing one
|
||||||
int func_counter2 = 0;
|
int func_counter2 = 0;
|
||||||
timer.Add([&] { func_counter2++; }, "duplicated_func",
|
timer.Add([&] { func_counter2++; }, "duplicated_func", kInitDelayUs,
|
||||||
kInitDelaySec * kSecond, kRepeat1Sec * kSecond);
|
kRepeat1Us);
|
||||||
|
|
||||||
ASSERT_EQ(0, func_counter1);
|
ASSERT_EQ(0, func_counter1);
|
||||||
ASSERT_EQ(0, func2_counter);
|
ASSERT_EQ(0, func2_counter);
|
||||||
ASSERT_EQ(0, func_counter2);
|
ASSERT_EQ(0, func_counter2);
|
||||||
|
|
||||||
mock_time_sec += kInitDelaySec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kInitDelayUs); });
|
||||||
|
|
||||||
ASSERT_EQ(0, func_counter1);
|
ASSERT_EQ(0, func_counter1);
|
||||||
ASSERT_EQ(1, func2_counter);
|
ASSERT_EQ(1, func2_counter);
|
||||||
ASSERT_EQ(1, func_counter2);
|
ASSERT_EQ(1, func_counter2);
|
||||||
|
|
||||||
mock_time_sec += kRepeat1Sec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kRepeat1Us); });
|
||||||
|
|
||||||
ASSERT_EQ(0, func_counter1);
|
ASSERT_EQ(0, func_counter1);
|
||||||
ASSERT_EQ(2, func2_counter);
|
ASSERT_EQ(2, func2_counter);
|
||||||
@ -317,39 +302,40 @@ TEST_F(TimerTest, AddSameFuncName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, RepeatIntervalWithFuncRunningTime) {
|
TEST_F(TimerTest, RepeatIntervalWithFuncRunningTime) {
|
||||||
const int kInitDelaySec = 1;
|
const int kInitDelayUs = 1 * kUsPerSec;
|
||||||
const int kRepeatSec = 5;
|
const int kRepeatUs = 5 * kUsPerSec;
|
||||||
const int kFuncRunningTimeSec = 1;
|
const int kFuncRunningTimeUs = 1 * kUsPerSec;
|
||||||
|
|
||||||
int mock_time_sec = 0;
|
|
||||||
mock_env_->set_current_time(mock_time_sec);
|
|
||||||
Timer timer(mock_env_.get());
|
Timer timer(mock_env_.get());
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Start());
|
ASSERT_TRUE(timer.Start());
|
||||||
|
|
||||||
int func_counter = 0;
|
int func_counter = 0;
|
||||||
timer.Add(
|
timer.Add(
|
||||||
[&] {
|
[&] {
|
||||||
mock_env_->set_current_time(mock_time_sec + kFuncRunningTimeSec);
|
mock_env_->MockSleepForMicroseconds(kFuncRunningTimeUs);
|
||||||
func_counter++;
|
func_counter++;
|
||||||
},
|
},
|
||||||
"func", kInitDelaySec * kSecond, kRepeatSec * kSecond);
|
"func", kInitDelayUs, kRepeatUs);
|
||||||
|
|
||||||
ASSERT_EQ(0, func_counter);
|
ASSERT_EQ(0, func_counter);
|
||||||
mock_time_sec += kInitDelaySec;
|
timer.TEST_WaitForRun(
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
[&] { mock_env_->MockSleepForMicroseconds(kInitDelayUs); });
|
||||||
ASSERT_EQ(1, func_counter);
|
ASSERT_EQ(1, func_counter);
|
||||||
|
ASSERT_EQ(kInitDelayUs + kFuncRunningTimeUs, mock_env_->NowMicros());
|
||||||
|
|
||||||
// After repeat interval time, the function is not executed, as running
|
// After repeat interval time, the function is not executed, as running
|
||||||
// the function takes some time (`kFuncRunningTimeSec`). The repeat interval
|
// the function takes some time (`kFuncRunningTimeSec`). The repeat interval
|
||||||
// is the time between ending time of the last call and starting time of the
|
// is the time between ending time of the last call and starting time of the
|
||||||
// next call.
|
// next call.
|
||||||
mock_time_sec += kRepeatSec;
|
uint64_t next_abs_interval_time_us = kInitDelayUs + kRepeatUs;
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
timer.TEST_WaitForRun([&] {
|
||||||
|
mock_env_->set_current_time(next_abs_interval_time_us / kUsPerSec);
|
||||||
|
});
|
||||||
ASSERT_EQ(1, func_counter);
|
ASSERT_EQ(1, func_counter);
|
||||||
|
|
||||||
mock_time_sec += kFuncRunningTimeSec;
|
// After the function running time, it's executed again
|
||||||
timer.TEST_WaitForRun([&] { mock_env_->set_current_time(mock_time_sec); });
|
timer.TEST_WaitForRun(
|
||||||
|
[&] { mock_env_->MockSleepForMicroseconds(kFuncRunningTimeUs); });
|
||||||
ASSERT_EQ(2, func_counter);
|
ASSERT_EQ(2, func_counter);
|
||||||
|
|
||||||
ASSERT_TRUE(timer.Shutdown());
|
ASSERT_TRUE(timer.Shutdown());
|
||||||
|
Loading…
Reference in New Issue
Block a user