573 lines
17 KiB
C++
573 lines
17 KiB
C++
/************************************************************************
|
|
*
|
|
* Copyright (c) 2016 Alibaba.com, Inc. All Rights Reserved
|
|
* $Id: consensus-t.cc,v 1.0 07/30/2016 02:41:21 PM yingqiang.zyq(yingqiang.zyq@alibaba-inc.com) $
|
|
*
|
|
************************************************************************/
|
|
|
|
/**
|
|
* @file consensus-t.cc
|
|
* @author yingqiang.zyq(yingqiang.zyq@alibaba-inc.com)
|
|
* @date 07/30/2016 02:41:21 PM
|
|
* @version 1.0
|
|
* @brief unit test for alisql::Consensus
|
|
*
|
|
**/
|
|
|
|
#include <atomic>
|
|
#include <thread>
|
|
#include <gtest/gtest.h>
|
|
#include "easyNet.h"
|
|
#include "service.h"
|
|
#include "paxos.h"
|
|
#include "paxos_log.h"
|
|
#include "paxos_server.h"
|
|
#include "paxos_configuration.h"
|
|
#include "paxos.pb.h"
|
|
#include "files.h"
|
|
|
|
#include "rd_paxos_log.h"
|
|
#include "file_paxos_log.h"
|
|
|
|
using namespace alisql;
|
|
|
|
TEST(consensus, Paxos_add_node2)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
//strConfig.emplace_back("127.0.0.1:11003");
|
|
std::string strTmp3("127.0.0.1:11003");
|
|
|
|
const uint64_t timeout= 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1= rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir1", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1= new Paxos(timeout, rlog);
|
|
paxos1->init(strConfig, 1);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir2", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2= new Paxos(timeout, rlog);
|
|
paxos2->init(strConfig, 2);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir3", true, 4 * 1024 * 1024);
|
|
Paxos *paxos3= new Paxos(timeout, rlog);
|
|
paxos3->initAsLearner(strTmp3);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
|
|
EXPECT_EQ(paxos1->getState(), Paxos::LEADER);
|
|
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp3);
|
|
|
|
paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
paxos1->changeMember(Paxos::CCAddNode, strTmp3);
|
|
|
|
sleep(1);
|
|
delete paxos1;
|
|
|
|
sleep(7);
|
|
EXPECT_TRUE(paxos2->getState() == Paxos::LEADER || paxos3->getState() == Paxos::LEADER);
|
|
sleep(2);
|
|
EXPECT_TRUE(paxos2->getState() == Paxos::LEADER || paxos3->getState() == Paxos::LEADER);
|
|
sleep(2);
|
|
EXPECT_TRUE(paxos2->getState() == Paxos::LEADER || paxos3->getState() == Paxos::LEADER);
|
|
|
|
|
|
delete paxos3;
|
|
delete paxos2;
|
|
|
|
deleteDir("paxosLogTestDir1");
|
|
deleteDir("paxosLogTestDir2");
|
|
deleteDir("paxosLogTestDir3");
|
|
}
|
|
|
|
TEST(consensus, Paxos_add_node3)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
strConfig.emplace_back("127.0.0.1:11003");
|
|
std::string strTmp3("127.0.0.1:11004");
|
|
std::string strTmp4("127.0.0.1:11005");
|
|
|
|
const uint64_t timeout= 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1= rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir11", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1= new Paxos(timeout, rlog);
|
|
paxos1->init(strConfig, 1);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir12", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2= new Paxos(timeout, rlog);
|
|
paxos2->init(strConfig, 2);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir13", true, 4 * 1024 * 1024);
|
|
Paxos *paxos3= new Paxos(timeout, rlog);
|
|
paxos3->init(strConfig, 3);
|
|
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir14", true, 4 * 1024 * 1024);
|
|
Paxos *paxos4= new Paxos(timeout, rlog);
|
|
paxos4->initAsLearner(strTmp3);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
|
|
EXPECT_EQ(paxos1->getState(), Paxos::LEADER);
|
|
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp3);
|
|
|
|
paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
paxos1->changeMember(Paxos::CCAddNode, strTmp3);
|
|
|
|
//sleep(1);
|
|
delete paxos1;
|
|
|
|
sleep(7);
|
|
EXPECT_TRUE(paxos2->getState() == Paxos::LEADER || paxos3->getState() == Paxos::LEADER || paxos4->getState() == Paxos::LEADER);
|
|
sleep(2);
|
|
EXPECT_TRUE(paxos2->getState() == Paxos::LEADER || paxos3->getState() == Paxos::LEADER || paxos4->getState() == Paxos::LEADER);
|
|
sleep(2);
|
|
EXPECT_TRUE(paxos2->getState() == Paxos::LEADER || paxos3->getState() == Paxos::LEADER || paxos4->getState() == Paxos::LEADER);
|
|
|
|
Paxos *leader;
|
|
if (paxos2->getState() == Paxos::LEADER)
|
|
leader= paxos2;
|
|
else if (paxos3->getState() == Paxos::LEADER)
|
|
leader= paxos3;
|
|
else
|
|
leader= paxos4;
|
|
EXPECT_EQ(leader->getState(), Paxos::LEADER);
|
|
|
|
|
|
//add a learner with different cluster id
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir15", true, 4 * 1024 * 1024);
|
|
rlog->setMetaData(Paxos::keyClusterId, 1);
|
|
Paxos *paxos5= new Paxos(timeout, rlog);
|
|
paxos5->initAsLearner(strTmp4);
|
|
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp4);
|
|
|
|
leader->changeLearners(Paxos::CCAddNode, strConfig);
|
|
|
|
sleep(2);
|
|
EXPECT_EQ(leader->getConfig()->learnersToString(), std::string("127.0.0.1:11005$00"));
|
|
EXPECT_EQ(paxos5->getLog()->getLastLogIndex(), 0);
|
|
|
|
delete paxos5;
|
|
delete paxos4;
|
|
delete paxos3;
|
|
delete paxos2;
|
|
|
|
deleteDir("paxosLogTestDir11");
|
|
deleteDir("paxosLogTestDir12");
|
|
deleteDir("paxosLogTestDir13");
|
|
deleteDir("paxosLogTestDir14");
|
|
deleteDir("paxosLogTestDir15");
|
|
}
|
|
|
|
TEST(consensus, Paxos_readd_node)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
std::string strTmp3("127.0.0.1:11003");
|
|
|
|
const uint64_t timeout= 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1= rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir1", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1= new Paxos(timeout, rlog);
|
|
paxos1->init(strConfig, 1);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir2", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2= new Paxos(timeout, rlog);
|
|
paxos2->init(strConfig, 2);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir3", true, 4 * 1024 * 1024);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
|
|
EXPECT_EQ(paxos1->getState(), Paxos::LEADER);
|
|
auto config= std::dynamic_pointer_cast<StableConfiguration>(paxos2->getConfig());
|
|
auto net= paxos1->getService()->getEasyNet();
|
|
|
|
//1st add 127.0.0.1:11003
|
|
Paxos *paxos3= new Paxos(timeout, rlog);
|
|
paxos3->initAsLearner(strTmp3);
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp3);
|
|
paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
sleep(1);
|
|
EXPECT_EQ(config->learnersToString(), strTmp3 + "$00");
|
|
EXPECT_EQ(net->getConnCnt(), 2);
|
|
|
|
paxos1->changeLearners(Paxos::CCDelNode, strConfig);
|
|
sleep(1);
|
|
EXPECT_EQ(config->learnersToString(), std::string(""));
|
|
EXPECT_EQ(net->getConnCnt(), 1);
|
|
|
|
delete paxos3;
|
|
paxos3= nullptr;
|
|
|
|
//2nd add 127.0.0.1:11003
|
|
paxos3= new Paxos(timeout, rlog);
|
|
paxos3->initAsLearner(strTmp3);
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp3);
|
|
paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
sleep(1);
|
|
EXPECT_EQ(config->learnersToString(), strTmp3 + "$00");
|
|
EXPECT_EQ(net->getConnCnt(), 2);
|
|
|
|
paxos1->changeLearners(Paxos::CCDelNode, strConfig);
|
|
sleep(1);
|
|
EXPECT_EQ(config->learnersToString(), std::string(""));
|
|
EXPECT_EQ(net->getConnCnt(), 1);
|
|
|
|
delete paxos3;
|
|
paxos3= nullptr;
|
|
|
|
//3rd add 127.0.0.1:11003
|
|
paxos3= new Paxos(timeout, rlog);
|
|
paxos3->initAsLearner(strTmp3);
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp3);
|
|
paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
sleep(1);
|
|
EXPECT_EQ(config->learnersToString(), strTmp3 + "$00");
|
|
EXPECT_EQ(net->getConnCnt(), 2);
|
|
|
|
paxos1->changeLearners(Paxos::CCDelNode, strConfig);
|
|
sleep(1);
|
|
EXPECT_EQ(config->learnersToString(), std::string(""));
|
|
EXPECT_EQ(net->getConnCnt(), 1);
|
|
|
|
delete paxos3;
|
|
paxos3= nullptr;
|
|
|
|
|
|
delete paxos1;
|
|
delete paxos2;
|
|
|
|
deleteDir("paxosLogTestDir1");
|
|
deleteDir("paxosLogTestDir2");
|
|
deleteDir("paxosLogTestDir3");
|
|
}
|
|
|
|
TEST(consensus, Paxos_add_delay_node)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
std::string strTmp1("127.0.0.1:11001");
|
|
std::string strTmp3("127.0.0.1:11003");
|
|
std::string strTmp4("127.0.0.1:11004");
|
|
|
|
const uint64_t timeout= 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1= rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir1", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1= new Paxos(timeout, rlog);
|
|
paxos1->init(strConfig, 1);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir2", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2= new Paxos(timeout, rlog);
|
|
paxos2->init(strConfig, 2);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir3", true, 4 * 1024 * 1024);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
|
|
//1st add 127.0.0.1:11003
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp3);
|
|
paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
sleep(1);
|
|
|
|
LogEntry le;
|
|
le.set_index(0);
|
|
le.set_optype(0);
|
|
le.set_value("aaa");
|
|
for (uint i= 0; i<20; ++i)
|
|
{
|
|
le.clear_term();
|
|
paxos1->replicateLog(le);
|
|
}
|
|
|
|
strConfig.clear();
|
|
strConfig.push_back(strTmp1);
|
|
auto ret= paxos1->changeLearners(Paxos::CCAddNode, strConfig);
|
|
EXPECT_EQ(PaxosErrorCode::PE_EXISTS, ret);
|
|
|
|
ret= paxos1->changeMember(Paxos::CCAddNode, strTmp4);
|
|
EXPECT_EQ(PaxosErrorCode::PE_NOTFOUND, ret);
|
|
|
|
paxos1->setMaxDelayIndex4NewMember(10);
|
|
ret= paxos1->changeMember(Paxos::CCAddNode, strTmp3);
|
|
EXPECT_EQ(PaxosErrorCode::PE_DELAY, ret);
|
|
|
|
paxos1->setMaxDelayIndex4NewMember(50);
|
|
ret= paxos1->changeMember(Paxos::CCAddNode, strTmp3);
|
|
EXPECT_EQ(0, ret);
|
|
|
|
|
|
delete paxos1;
|
|
delete paxos2;
|
|
|
|
deleteDir("paxosLogTestDir1");
|
|
deleteDir("paxosLogTestDir2");
|
|
deleteDir("paxosLogTestDir3");
|
|
}
|
|
|
|
TEST(consensus, Paxos_add_follower)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
std::string strTmp3("127.0.0.1:11003");
|
|
|
|
const uint64_t timeout= 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1= rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir1", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1= new Paxos(timeout, rlog);
|
|
paxos1->setMaxDelayIndex4NewMember(2);
|
|
paxos1->init(strConfig, 1);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir2", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2= new Paxos(timeout, rlog);
|
|
paxos2->setMaxDelayIndex4NewMember(2);
|
|
paxos2->init(strConfig, 2);
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir3", true, 4 * 1024 * 1024);
|
|
Paxos *paxos3= new Paxos(timeout, rlog);
|
|
paxos3->setMaxDelayIndex4NewMember(2);
|
|
paxos3->initAsLearner(strTmp3);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
EXPECT_EQ(paxos1->getState(), Paxos::LEADER);
|
|
|
|
LogEntry le;
|
|
le.set_index(0);
|
|
le.set_optype(1);
|
|
le.set_value("log1");
|
|
paxos1->replicateLog(le);
|
|
le.set_index(0);
|
|
le.set_optype(1);
|
|
le.set_value("log2");
|
|
paxos1->replicateLog(le);
|
|
|
|
/* basic case (sync) */
|
|
EXPECT_EQ(paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3), 0);
|
|
std::vector<Paxos::ClusterInfoType> cis;
|
|
paxos1->getClusterInfo(cis);
|
|
paxos1->printClusterInfo(cis);
|
|
EXPECT_EQ(cis.size(), 3);
|
|
sleep(2);
|
|
EXPECT_EQ(paxos3->getState(), Paxos::FOLLOWER);
|
|
|
|
/* run paxos after addFollower */
|
|
strTmp3 = "127.0.0.1:11004";
|
|
rlog= std::make_shared<RDPaxosLog>("paxosLogTestDir4", true, 4 * 1024 * 1024);
|
|
Paxos *paxos4= new Paxos(timeout, rlog);
|
|
paxos4->setMaxDelayIndex4NewMember(2);
|
|
|
|
std::thread th1([paxos4, &strTmp3](int sleeptime) {
|
|
sleep(sleeptime);
|
|
paxos4->initAsLearner(strTmp3);
|
|
}, 5);
|
|
|
|
EXPECT_EQ(paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3), 0);
|
|
paxos1->getClusterInfo(cis);
|
|
paxos1->printClusterInfo(cis);
|
|
EXPECT_EQ(cis.size(), 4);
|
|
|
|
th1.join();
|
|
sleep(2);
|
|
EXPECT_EQ(paxos4->getState(), Paxos::FOLLOWER);
|
|
|
|
delete paxos1;
|
|
delete paxos3;
|
|
delete paxos4;
|
|
delete paxos2;
|
|
|
|
deleteDir("paxosLogTestDir1");
|
|
deleteDir("paxosLogTestDir2");
|
|
deleteDir("paxosLogTestDir3");
|
|
deleteDir("paxosLogTestDir4");
|
|
}
|
|
|
|
TEST(consensus, Paxos_add_follower2)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
std::string strTmp3("127.0.0.1:11003");
|
|
|
|
const uint64_t timeout = 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1 = rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir1", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1 = new Paxos(timeout, rlog);
|
|
paxos1->setMaxDelayIndex4NewMember(2);
|
|
paxos1->init(strConfig, 1);
|
|
rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir2", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2 = new Paxos(timeout, rlog);
|
|
paxos2->setMaxDelayIndex4NewMember(2);
|
|
paxos2->init(strConfig, 2);
|
|
rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir3", true, 4 * 1024 * 1024);
|
|
Paxos *paxos3 = new Paxos(timeout, rlog);
|
|
paxos3->setMaxDelayIndex4NewMember(2);
|
|
paxos3->initAsLearner(strTmp3);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
EXPECT_EQ(paxos1->getState(), Paxos::LEADER);
|
|
|
|
LogEntry le;
|
|
le.set_index(0);
|
|
le.set_optype(1);
|
|
le.set_value("log1");
|
|
paxos1->replicateLog(le);
|
|
le.set_index(0);
|
|
le.set_optype(1);
|
|
le.set_value("log2");
|
|
paxos1->replicateLog(le);
|
|
|
|
/* basic case (async, timeout=5000) */
|
|
paxos1->setConfigureChangeTimeout(5000);
|
|
EXPECT_EQ(paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3), 0);
|
|
EXPECT_EQ(paxos3->getState(), Paxos::LEARNER);
|
|
sleep(2);
|
|
std::vector<Paxos::ClusterInfoType> cis;
|
|
paxos1->getClusterInfo(cis);
|
|
paxos1->printClusterInfo(cis);
|
|
EXPECT_EQ(cis.size(), 3);
|
|
sleep(2);
|
|
EXPECT_EQ(paxos3->getState(), Paxos::FOLLOWER);
|
|
|
|
/* leader transfer during addFollower */
|
|
strTmp3 = "127.0.0.1:11004";
|
|
rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir4", true, 4 * 1024 * 1024);
|
|
Paxos *paxos4 = new Paxos(timeout, rlog);
|
|
paxos4->setMaxDelayIndex4NewMember(2);
|
|
|
|
std::thread th1([paxos1]() {
|
|
sleep(1);
|
|
paxos1->leaderTransfer(2);
|
|
});
|
|
|
|
std::thread th2([paxos4, &strTmp3]() {
|
|
sleep(3);
|
|
paxos4->initAsLearner(strTmp3);
|
|
});
|
|
|
|
paxos1->setConfigureChangeTimeout(0);
|
|
EXPECT_EQ(paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3), -1);
|
|
paxos2->getClusterInfo(cis);
|
|
paxos2->printClusterInfo(cis);
|
|
EXPECT_EQ(cis.size(), 4);
|
|
|
|
th1.join();
|
|
th2.join();
|
|
sleep(4);
|
|
EXPECT_EQ(paxos4->getState(), Paxos::FOLLOWER);
|
|
|
|
delete paxos1;
|
|
delete paxos2;
|
|
delete paxos3;
|
|
delete paxos4;
|
|
deleteDir("paxosLogTestDir1");
|
|
deleteDir("paxosLogTestDir2");
|
|
deleteDir("paxosLogTestDir3");
|
|
deleteDir("paxosLogTestDir4");
|
|
}
|
|
|
|
TEST(consensus, Paxos_add_follower3)
|
|
{
|
|
std::vector<std::string> strConfig;
|
|
strConfig.emplace_back("127.0.0.1:11001");
|
|
strConfig.emplace_back("127.0.0.1:11002");
|
|
std::string strTmp3("127.0.0.1:11003");
|
|
|
|
const uint64_t timeout = 2000;
|
|
std::shared_ptr<PaxosLog> rlog, rlog1;
|
|
rlog1 = rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir1", true, 4 * 1024 * 1024);
|
|
Paxos *paxos1 = new Paxos(timeout, rlog);
|
|
paxos1->setMaxDelayIndex4NewMember(2);
|
|
paxos1->init(strConfig, 1);
|
|
rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir2", true, 4 * 1024 * 1024);
|
|
Paxos *paxos2 = new Paxos(timeout, rlog);
|
|
paxos2->setMaxDelayIndex4NewMember(2);
|
|
paxos2->init(strConfig, 2);
|
|
rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir3", true, 4 * 1024 * 1024);
|
|
Paxos *paxos3 = new Paxos(timeout, rlog);
|
|
paxos3->setMaxDelayIndex4NewMember(2);
|
|
|
|
sleep(3);
|
|
paxos1->requestVote();
|
|
sleep(1);
|
|
EXPECT_EQ(paxos1->getState(), Paxos::LEADER);
|
|
|
|
LogEntry le;
|
|
le.set_index(0);
|
|
le.set_optype(1);
|
|
le.set_value("log1");
|
|
paxos1->replicateLog(le);
|
|
le.set_index(0);
|
|
le.set_optype(1);
|
|
le.set_value("log2");
|
|
paxos1->replicateLog(le);
|
|
|
|
/* basic case (async, trigger timeout retcode) */
|
|
paxos1->setConfigureChangeTimeout(100);
|
|
EXPECT_EQ(paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3), PaxosErrorCode::PE_TIMEOUT);
|
|
/* retry is ok */
|
|
paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3);
|
|
paxos3->initAsLearner(strTmp3);
|
|
paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3);
|
|
|
|
sleep(2);
|
|
std::vector<Paxos::ClusterInfoType> cis;
|
|
paxos1->getClusterInfo(cis);
|
|
paxos1->printClusterInfo(cis);
|
|
EXPECT_EQ(cis.size(), 3);
|
|
sleep(2);
|
|
EXPECT_EQ(paxos3->getState(), Paxos::FOLLOWER);
|
|
|
|
/* learner is deleted during addFollower */
|
|
strTmp3 = "127.0.0.1:11004";
|
|
rlog = std::make_shared<RDPaxosLog>("paxosLogTestDir4", true, 4 * 1024 * 1024);
|
|
Paxos *paxos4 = new Paxos(timeout, rlog);
|
|
paxos4->setMaxDelayIndex4NewMember(2);
|
|
|
|
std::thread th1([paxos1, &strTmp3]() {
|
|
sleep(1);
|
|
std::vector<std::string> strConfig{strTmp3};
|
|
paxos1->changeLearners(Paxos::CCDelNode, strConfig);
|
|
});
|
|
|
|
std::thread th2([paxos4, &strTmp3]() {
|
|
sleep(3);
|
|
paxos4->initAsLearner(strTmp3);
|
|
});
|
|
|
|
paxos1->setConfigureChangeTimeout(0);
|
|
EXPECT_EQ(paxos1->changeMember(Paxos::CCAddLearnerAutoChange, strTmp3), -2);
|
|
paxos1->getClusterInfo(cis);
|
|
paxos1->printClusterInfo(cis);
|
|
EXPECT_EQ(cis.size(), 3); /* still 3 not 4 */
|
|
|
|
th1.join();
|
|
th2.join();
|
|
sleep(2);
|
|
|
|
delete paxos1;
|
|
delete paxos2;
|
|
delete paxos3;
|
|
delete paxos4;
|
|
deleteDir("paxosLogTestDir1");
|
|
deleteDir("paxosLogTestDir2");
|
|
deleteDir("paxosLogTestDir3");
|
|
deleteDir("paxosLogTestDir4");
|
|
}
|
|
|