173 lines
6.5 KiB
C++
173 lines
6.5 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <random>
|
|
#include <string>
|
|
#define private public
|
|
#include "mock_logservice_container/mock_log_engine.h"
|
|
#include "mock_logservice_container/mock_election.h"
|
|
#include "mock_logservice_container/mock_log_sliding_window.h"
|
|
#include "mock_logservice_container/mock_log_reconfirm.h"
|
|
#include "mock_logservice_container/mock_log_config_mgr.h"
|
|
#include "mock_logservice_container/mock_log_mode_mgr.h"
|
|
#include "mock_logservice_container/mock_palf_role_change_cb_wrapper.h"
|
|
#include "logservice/palf/log_state_mgr.h"
|
|
#undef private
|
|
|
|
namespace oceanbase
|
|
{
|
|
using namespace common;
|
|
using namespace palf;
|
|
using namespace share;
|
|
|
|
namespace unittest
|
|
{
|
|
|
|
class TestLogStateMgr: public ::testing::Test
|
|
{
|
|
public:
|
|
TestLogStateMgr();
|
|
virtual ~TestLogStateMgr();
|
|
public:
|
|
virtual void SetUp();
|
|
virtual void TearDown();
|
|
public:
|
|
int64_t palf_id_;
|
|
common::ObAddr self_;
|
|
LogPrepareMeta log_prepare_meta_;
|
|
LogReplicaPropertyMeta log_replica_property_meta_;
|
|
::oceanbase::palf::mockelection::MockElection mock_election_;
|
|
MockLogSlidingWindow mock_sw_;
|
|
MockLogReconfirm mock_reconfirm_;
|
|
MockLogEngine mock_log_engine_;
|
|
MockLogConfigMgr mock_config_mgr_;
|
|
MockLogModeMgr mock_mode_mgr_;
|
|
MockPalfRoleChangeCbWrapper mock_role_change_cb_;
|
|
LogStateMgr state_mgr_;
|
|
};
|
|
|
|
TestLogStateMgr::TestLogStateMgr() {}
|
|
TestLogStateMgr::~TestLogStateMgr() {}
|
|
|
|
void TestLogStateMgr::SetUp()
|
|
{
|
|
palf_id_ = 1001;
|
|
self_.set_ip_addr("127.0.0.1", 12345);
|
|
LogVotedFor voted_for;
|
|
log_prepare_meta_.generate(voted_for, 1);
|
|
log_replica_property_meta_.generate(true, LogReplicaType::NORMAL_REPLICA);
|
|
}
|
|
|
|
void TestLogStateMgr::TearDown()
|
|
{}
|
|
|
|
TEST_F(TestLogStateMgr, test_init)
|
|
{
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, state_mgr_.init(palf_id_, self_, log_prepare_meta_, log_replica_property_meta_, NULL, &mock_sw_,
|
|
&mock_reconfirm_, &mock_log_engine_, &mock_config_mgr_, &mock_mode_mgr_, &mock_role_change_cb_));
|
|
EXPECT_EQ(OB_INVALID_ARGUMENT, state_mgr_.init(palf_id_, self_, log_prepare_meta_, log_replica_property_meta_, &mock_election_, NULL,
|
|
&mock_reconfirm_, &mock_log_engine_, &mock_config_mgr_, &mock_mode_mgr_, &mock_role_change_cb_));
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.init(palf_id_, self_, log_prepare_meta_, log_replica_property_meta_, &mock_election_, &mock_sw_,
|
|
&mock_reconfirm_, &mock_log_engine_, &mock_config_mgr_, &mock_mode_mgr_, &mock_role_change_cb_));
|
|
EXPECT_EQ(OB_INIT_TWICE, state_mgr_.init(palf_id_, self_, log_prepare_meta_, log_replica_property_meta_, &mock_election_, &mock_sw_,
|
|
&mock_reconfirm_, &mock_log_engine_, &mock_config_mgr_, &mock_mode_mgr_, &mock_role_change_cb_));
|
|
}
|
|
|
|
TEST_F(TestLogStateMgr, replay_to_leader_active)
|
|
{
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.init(palf_id_, self_, log_prepare_meta_, log_replica_property_meta_, &mock_election_, &mock_sw_,
|
|
&mock_reconfirm_, &mock_log_engine_, &mock_config_mgr_, &mock_mode_mgr_, &mock_role_change_cb_));
|
|
// set default config meta
|
|
ObMemberList default_mlist;
|
|
default_mlist.add_server(self_);
|
|
GlobalLearnerList learners;
|
|
LogConfigMeta config_meta;
|
|
LogConfigInfo init_config_info;
|
|
LogConfigVersion init_config_version;
|
|
EXPECT_EQ(OB_SUCCESS, init_config_version.generate(1, 0));
|
|
EXPECT_EQ(OB_SUCCESS, init_config_info.generate(default_mlist, 1, learners, init_config_version));
|
|
config_meta.curr_ = init_config_info;
|
|
mock_config_mgr_.log_ms_meta_ = config_meta;
|
|
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.set_scan_disk_log_finished());
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state()); // replay to follower active
|
|
EXPECT_EQ(true, state_mgr_.is_follower_active());
|
|
mock_config_mgr_.self_ = self_;
|
|
mock_election_.self_ = self_;
|
|
|
|
// test follower to leader
|
|
mock_election_.leader_ = self_;
|
|
mock_election_.leader_epoch_ = 10;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_leader_active());
|
|
|
|
// test leader to follower
|
|
mock_election_.leader_.reset();
|
|
mock_election_.leader_epoch_ = 0;
|
|
mock_sw_.pending_end_lsn_.val_ = 100;
|
|
mock_sw_.last_slide_end_lsn_.val_ = 90;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_follower_pending());
|
|
mock_sw_.last_slide_end_lsn_.val_ = 100;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_follower_active());
|
|
|
|
// test follower pending to reconfirm to leader active
|
|
mock_election_.leader_ = self_;
|
|
mock_election_.leader_epoch_ = 11;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_leader_active());
|
|
mock_election_.leader_.reset();
|
|
mock_election_.leader_epoch_ = 0;
|
|
mock_sw_.pending_end_lsn_.val_ = 200;
|
|
mock_sw_.last_slide_end_lsn_.val_ = 190;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_follower_pending());
|
|
// pending to reconfirm
|
|
mock_election_.leader_ = self_;
|
|
mock_election_.leader_epoch_ = 12;
|
|
mock_reconfirm_.mock_ret_ = OB_EAGAIN;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_leader_reconfirm());
|
|
// reconfirm to pending
|
|
mock_election_.leader_.reset();
|
|
mock_election_.leader_epoch_ = 0;
|
|
mock_sw_.pending_end_lsn_.val_ = 300;
|
|
mock_sw_.last_slide_end_lsn_.val_ = 290;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_follower_pending());
|
|
// pending to reconfirm
|
|
mock_election_.leader_ = self_;
|
|
mock_election_.leader_epoch_ = 13;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_leader_reconfirm());
|
|
// reconfirm to pending
|
|
// reconfirm to leader active
|
|
mock_reconfirm_.mock_ret_ = OB_SUCCESS;
|
|
EXPECT_EQ(OB_SUCCESS, state_mgr_.switch_state());
|
|
EXPECT_EQ(true, state_mgr_.is_leader_active());
|
|
}
|
|
|
|
} // END of unittest
|
|
} // end of oceanbase
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
system("rm -f ./test_log_state_mgr.log");
|
|
OB_LOGGER.set_file_name("test_log_state_mgr.log", true);
|
|
OB_LOGGER.set_log_level("TRACE");
|
|
PALF_LOG(INFO, "begin unittest::test_log_state_mgr");
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|