diff --git a/library/cpp/sandesh_client.cc b/library/cpp/sandesh_client.cc index 0ec2a4b9..cb76feee 100644 --- a/library/cpp/sandesh_client.cc +++ b/library/cpp/sandesh_client.cc @@ -114,17 +114,7 @@ void SandeshClient::Shutdown() { } bool SandeshClient::SendSandesh(Sandesh *snh) { - if (!sm_->session() || sm_->session()->IsClosed()) { - return false; - } - SandeshClientSM::State state = sm_->state(); - if (state != SandeshClientSM::CLIENT_INIT && - state != SandeshClientSM::ESTABLISHED) { - return false; - } - // XXX No bounded work queue - sm_->session()->send_queue()->Enqueue(snh); - return true; + return sm_->SendSandesh(snh); } bool SandeshClient::ReceiveCtrlMsg(const std::string &msg, diff --git a/library/cpp/sandesh_client.h b/library/cpp/sandesh_client.h index 678f84ee..7949baf0 100644 --- a/library/cpp/sandesh_client.h +++ b/library/cpp/sandesh_client.h @@ -47,7 +47,7 @@ class SandeshClient : public TcpServer, public SandeshClientSM::Mgr { void Initiate(); void Shutdown(); - SandeshSession *CreateSMSession( + virtual SandeshSession *CreateSMSession( TcpSession::EventObserver eocb, SandeshReceiveMsgCb rmcb, TcpServer::Endpoint ep); @@ -82,6 +82,10 @@ class SandeshClient : public TcpServer, public SandeshClientSM::Mgr { return sm_->session(); } + SandeshClientSM* state_machine() const { + return sm_.get(); + } + void SetSessionWaterMarkInfo(Sandesh::QueueWaterMarkInfo &scwm); void ResetSessionWaterMarkInfo(); void GetSessionWaterMarkInfo( diff --git a/library/cpp/sandesh_client_sm.cc b/library/cpp/sandesh_client_sm.cc index df739eb1..27a7375c 100644 --- a/library/cpp/sandesh_client_sm.cc +++ b/library/cpp/sandesh_client_sm.cc @@ -491,14 +491,21 @@ struct ClientInit : public sc::state { sc::result react(const EvSandeshSend &event) { SandeshClientSMImpl *state_machine = &context(); - SM_LOG(DEBUG, state_machine->StateName() << " : " << event.Name() << " : " << event.snh->Name()); - if (dynamic_cast(event.snh)) { - SM_LOG(INFO, "Received UVE message in wrong state : " << event.snh->Name()); - event.snh->Release(); + Sandesh *snh(event.snh); + SM_LOG(DEBUG, state_machine->StateName() << " : " << event.Name() << + " : " << snh->Name()); + if (dynamic_cast(snh)) { + if (snh->IsLoggingDroppedAllowed()) { + SANDESH_LOG(ERROR, "SANDESH: Send FAILED: " << + snh->ToString()); + } + Sandesh::UpdateSandeshStats(snh->Name(), 0, true, true); + SM_LOG(INFO, "Received UVE message in wrong state : " << snh->Name()); + snh->Release(); return discard_event(); } - if (!state_machine->send_session(event.snh)) { - SM_LOG(ERROR, "Could not EnQ Sandesh " << event.snh->Name()); + if (!state_machine->send_session(snh)) { + SM_LOG(INFO, "Could not EnQ Sandesh :" << snh->Name()); // If Enqueue encounters an error, it will release the Sandesh } return discard_event(); @@ -634,7 +641,7 @@ struct Established : public sc::state { void SandeshClientSMImpl::SetAdminState(bool down) { if (down) { - Enqueue(scm::EvStop(false)); + Enqueue(scm::EvStop()); } else { reset_idle_hold_time(); // On fresh restart of state machine, all previous state should be reset @@ -659,8 +666,14 @@ void SandeshClientSMImpl::OnIdle(const Ev &event) { template void SandeshClientSMImpl::ReleaseSandesh(const Ev &event) { - SM_LOG(DEBUG, "Wrong state: " << StateName() << " for event: " << event.Name()); - event.snh->Release(); + Sandesh *snh(event.snh); + if (snh->IsLoggingDroppedAllowed()) { + SANDESH_LOG(ERROR, "SANDESH: Send FAILED: " << snh->ToString()); + } + Sandesh::UpdateSandeshStats(snh->Name(), 0, true, true); + SM_LOG(DEBUG, "Wrong state: " << StateName() << " for event: " << + event.Name() << " message: " << snh->Name()); + snh->Release(); } template @@ -766,6 +779,11 @@ bool SandeshClientSMImpl::SendSandeshUVE(Sandesh * snh) { return true; } +bool SandeshClientSMImpl::SendSandesh(Sandesh * snh) { + Enqueue(scm::EvSandeshSend(snh)); + return true; +} + void SandeshClientSMImpl::OnMessage(SandeshSession *session, const std::string &msg) { // Demux based on Sandesh message type @@ -796,6 +814,11 @@ static const std::string state_names[] = { "Established", }; +const string &SandeshClientSMImpl::StateName( + SandeshClientSM::State state) const { + return state_names[state]; +} + const string &SandeshClientSMImpl::StateName() const { return state_names[state_]; } diff --git a/library/cpp/sandesh_client_sm.h b/library/cpp/sandesh_client_sm.h index 94a78844..21fb717f 100644 --- a/library/cpp/sandesh_client_sm.h +++ b/library/cpp/sandesh_client_sm.h @@ -80,6 +80,9 @@ class SandeshClientSM { // This function is used to send UVE sandesh's to the server virtual bool SendSandeshUVE(Sandesh* snh) = 0; + // This function is used to send sandesh's to the server + virtual bool SendSandesh(Sandesh* snh) = 0; + virtual ~SandeshClientSM() {} protected: diff --git a/library/cpp/sandesh_client_sm_priv.h b/library/cpp/sandesh_client_sm_priv.h index 0df579e1..613cc420 100644 --- a/library/cpp/sandesh_client_sm_priv.h +++ b/library/cpp/sandesh_client_sm_priv.h @@ -63,6 +63,7 @@ class SandeshClientSMImpl : public SandeshClientSM, void GetCandidates(TcpServer::Endpoint& active, TcpServer::Endpoint &backup) const; bool SendSandeshUVE(Sandesh* snh); + bool SendSandesh(Sandesh* snh); void EnqueDelSession(SandeshSession * session); // Feed session events into the state machine. @@ -95,6 +96,7 @@ class SandeshClientSMImpl : public SandeshClientSM, int GetConnectTime() const; const std::string &StateName() const; + const std::string &StateName(SandeshClientSM::State state) const; const std::string &LastStateName() const; void set_state(State state) { @@ -178,6 +180,8 @@ class SandeshClientSMImpl : public SandeshClientSM, std::string generator_key_; SandeshEventStatistics event_stats_; + friend class SandeshClientStateMachineTest; + DISALLOW_COPY_AND_ASSIGN(SandeshClientSMImpl); }; diff --git a/library/cpp/test/SConscript b/library/cpp/test/SConscript index 0a3750b9..29e65f28 100644 --- a/library/cpp/test/SConscript +++ b/library/cpp/test/SConscript @@ -122,17 +122,18 @@ sandesh_http_test = env.UnitTest('sandesh_http_test', env.Alias('src/sandesh:sandesh_http_test', sandesh_http_test) env.Requires(sandesh_http_test, '#/build/include/libxml2/libxml/tree.h') +sandesh_test_common_obj = env.Object('sandesh_test_common.cc') sandesh_state_machine_test = env.UnitTest('sandesh_state_machine_test', - ['sandesh_state_machine_test.cc'] + ['sandesh_state_machine_test.cc'] + + sandesh_test_common_obj ) env.Alias('src/sandesh:sandesh_state_machine_test', sandesh_state_machine_test) -''' sandesh_client_test = env.UnitTest('sandesh_client_test', - ['sandesh_client_test.cc'] + ['sandesh_client_test.cc'] + + sandesh_test_common_obj ) env.Alias('src/sandesh:sandesh_client_test', sandesh_client_test) -''' test_suite = [sandesh_message_test, sandesh_rw_test, @@ -141,7 +142,7 @@ test_suite = [sandesh_message_test, sandesh_http_test, sandesh_state_machine_test, sandesh_perf_test, -# sandesh_client_test, + sandesh_client_test, ] test = env.TestSuite('sandesh-test', test_suite) diff --git a/library/cpp/test/sandesh_client_test.cc b/library/cpp/test/sandesh_client_test.cc index e63a9d89..756a57cf 100644 --- a/library/cpp/test/sandesh_client_test.cc +++ b/library/cpp/test/sandesh_client_test.cc @@ -16,14 +16,13 @@ #include "io/event_manager.h" #include "testing/gunit.h" -#include -#include #include #include -#include #include -#include "sandesh_factory.h" -#include "sandesh_client.h" +#include +#include +#include "sandesh_client_sm_priv.h" +#include "sandesh_test_common.h" using namespace std; using namespace boost::assign; @@ -32,6 +31,8 @@ using boost::system::error_code; using namespace contrail::sandesh::protocol; using namespace contrail::sandesh::transport; +typedef boost::asio::ip::tcp::endpoint Endpoint; + class SandeshSessionMock : public SandeshSession { public: enum State { @@ -46,7 +47,11 @@ class SandeshSessionMock : public SandeshSession { }; SandeshSessionMock(TcpServer *server, State state, Direction direction) - : SandeshSession(server, NULL), state_(state), direction_(direction) { + : SandeshSession(server, NULL, Task::kTaskInstanceAny, + TaskScheduler::GetInstance()->GetTaskId("sandesh::Test::ClientSM"), + TaskScheduler::GetInstance()->GetTaskId("io::ReaderTask")), + state_(state), + direction_(direction) { } ~SandeshSessionMock() { @@ -57,6 +62,11 @@ class SandeshSessionMock : public SandeshSession { return true; } + void Close() { + state_ = SandeshSessionMock::CLOSE; + SandeshSession::Close(); + } + virtual bool Connected(Endpoint remote) { state_ = SandeshSessionMock::CLIENT_INIT; EventObserver obs = observer(); @@ -66,11 +76,6 @@ class SandeshSessionMock : public SandeshSession { return true; } - void Close() { - state_ = SandeshSessionMock::CLOSE; - SandeshSession::Close(); - } - State state() { return state_; } Direction direction() { return direction_; } @@ -79,7 +84,6 @@ class SandeshSessionMock : public SandeshSession { Direction direction_; }; - class SandeshClientMock : public SandeshClient { public: SandeshClientMock(EventManager *evm, Endpoint dummy) : @@ -95,6 +99,17 @@ class SandeshClientMock : public SandeshClient { virtual void Connect(TcpSession *session, Endpoint remote) { } + virtual SandeshSession *CreateSMSession( + TcpSession::EventObserver eocb, + SandeshReceiveMsgCb rmcb, + TcpServer::Endpoint ep) { + SandeshSession *session(dynamic_cast( + CreateSession())); + session->SetReceiveMsgCb(rmcb); + session->set_observer(eocb); + return session; + } + virtual TcpSession *CreateSession() { if (session_) { assert(!old_session_); @@ -121,7 +136,7 @@ class SandeshClientMock : public SandeshClient { virtual bool ReceiveSandeshMsg(SandeshSession *session, const string& cmsg, const string& message_type, - const SandeshHeader& header, uint32_t xml_offset) { + const SandeshHeader& header, uint32_t xml_offset) { return true; } @@ -132,57 +147,14 @@ class SandeshClientMock : public SandeshClient { SandeshSessionMock *old_session_; }; -const std::string FakeMessageSandeshBegin(""); - -static void CreateFakeMessage(uint8_t *data, size_t length) { - size_t offset = 0; - SandeshHeader header; - // Populate the header - header.set_Namespace("Test"); - header.set_Timestamp(123456); - header.set_Module("SandeshStateMachineTest"); - header.set_Source("TestMachine"); - header.set_Context(""); - header.set_SequenceNum(0); - header.set_VersionSig(0); - header.set_Type(SandeshType::SYSTEM); - header.set_Hints(0); - header.set_Level(SandeshLevel::SYS_DEBUG); - header.set_Category("SSM"); - boost::shared_ptr btrans = - boost::shared_ptr( - new TMemoryBuffer(512)); - boost::shared_ptr prot = - boost::shared_ptr( - new TXMLProtocol(btrans)); - // Write the sandesh header - int ret = header.write(prot); - EXPECT_GT(ret, 0); - EXPECT_GT(length, offset + ret); - // Get the buffer - uint8_t *hbuffer; - uint32_t hlen; - btrans->getBuffer(&hbuffer, &hlen); - EXPECT_EQ(hlen, ret); - memcpy(data + offset, hbuffer, hlen); - offset += hlen; - EXPECT_GT(length, offset + FakeMessageSandeshBegin.size()); - memcpy(data + offset, FakeMessageSandeshBegin.c_str(), - FakeMessageSandeshBegin.size()); - offset += FakeMessageSandeshBegin.size(); - memset(data + offset, '0', length - offset); - offset += length - offset; - EXPECT_EQ(offset, length); -} - - class SandeshClientStateMachineTest : public ::testing::Test { protected: SandeshClientStateMachineTest() : - client_(new SandeshClientMock((&evm_), dummy_)), - timer_(TimerManager::CreateTimer(*evm_.io_service(), "Dummy timer")) { + client_(new SandeshClientMock((&evm_), Endpoint())), + timer_(TimerManager::CreateTimer(*evm_.io_service(), "Dummy timer")), + sm_(dynamic_cast(client_->state_machine())) { task_util::WaitForIdle(); - client_->set_idle_hold_time(1); + sm_->set_idle_hold_time(1); } ~SandeshClientStateMachineTest() { @@ -207,11 +179,11 @@ class SandeshClientStateMachineTest : public ::testing::Test { return false; } - void RunToState(scm::SsmState state) { + void RunToState(SandeshClientSM::State state) { timer_->Start(15000, boost::bind(&SandeshClientStateMachineTest::DummyTimerHandler, this)); task_util::WaitForIdle(); - for (int count = 0; count < 100 && client_->get_state() != state; count++) { + for (int count = 0; count < 100 && sm_->get_state() != state; count++) { evm_.RunOnce(); task_util::WaitForIdle(); } @@ -219,24 +191,24 @@ class SandeshClientStateMachineTest : public ::testing::Test { VerifyState(state); } - void GetToState(scm::SsmState state) { + void GetToState(SandeshClientSM::State state) { switch (state) { - case scm::IDLE: { + case SandeshClientSM::IDLE: { EvAdminDown(); VerifyState(state); break; } - case scm::CONNECT: { - GetToState(scm::IDLE); + case SandeshClientSM::CONNECT: { + GetToState(SandeshClientSM::IDLE); EvAdminUp(); RunToState(state); break; } - case scm::CLIENT_INIT: { - GetToState(scm::CONNECT); + case SandeshClientSM::CLIENT_INIT: { + GetToState(SandeshClientSM::CONNECT); Endpoint endpoint; client_->session()->Connected(endpoint); - VerifyState(scm::CLIENT_INIT); + VerifyState(SandeshClientSM::CLIENT_INIT); break; } default: { @@ -246,25 +218,25 @@ class SandeshClientStateMachineTest : public ::testing::Test { } } - void VerifyState(scm::SsmState state) { + void VerifyState(SandeshClientSM::State state) { task_util::WaitForIdle(); TaskScheduler::GetInstance()->Stop(); LOG(DEBUG, "VerifyState " << state); - EXPECT_EQ(state, client_->get_state()); + EXPECT_EQ(state, sm_->get_state()); switch (state) { - case scm::IDLE: + case SandeshClientSM::IDLE: EXPECT_TRUE(!ConnectTimerRunning()); EXPECT_TRUE(client_->session() == NULL); break; - case scm::CONNECT: + case SandeshClientSM::CONNECT: EXPECT_TRUE(ConnectTimerRunning()); EXPECT_TRUE(!IdleHoldTimerRunning()); EXPECT_TRUE(client_->session() != NULL); break; - case scm::CLIENT_INIT: - EXPECT_TRUE(!ConnectTimerRunning()); + case SandeshClientSM::CLIENT_INIT: + EXPECT_TRUE(ConnectTimerRunning()); EXPECT_TRUE(!IdleHoldTimerRunning()); EXPECT_TRUE(client_->session() != NULL); break; @@ -289,50 +261,44 @@ class SandeshClientStateMachineTest : public ::testing::Test { return session; } - void EvStart() { - client_->Initiate(); - } - void EvStop() { - client_->Shutdown(); - } void EvAdminUp() { - client_->SetAdminState(false); - client_->set_idle_hold_time(1); + sm_->SetAdminState(false); + sm_->set_idle_hold_time(1); } void EvAdminDown() { - client_->SetAdminState(true); - client_->set_idle_hold_time(1); + sm_->SetAdminState(true); + sm_->set_idle_hold_time(1); } void EvConnectTimerExpired() { - client_->FireConnectTimer(); + sm_->FireConnectTimer(); } void EvTcpConnected() { - client_->OnSessionEvent(client_->session(), + sm_->OnSessionEvent(client_->session(), TcpSession::CONNECT_COMPLETE); } void EvTcpConnectFail() { - client_->OnSessionEvent(client_->session(), + sm_->OnSessionEvent(client_->session(), TcpSession::CONNECT_FAILED); } void EvTcpClose(SandeshSessionMock *session = NULL) { if (!session) session = client_->session(); - client_->OnSessionEvent(session, TcpSession::CLOSE); + sm_->OnSessionEvent(session, TcpSession::CLOSE); } void EvSandeshMessageRecv(SandeshSessionMock *session = NULL) { session = GetSession(session); uint8_t msg[1024]; CreateFakeMessage(msg, sizeof(msg)); string xml((const char *)msg, sizeof(msg)); - client_->OnMessage(session, xml); + sm_->OnMessage(session, xml); } - bool IdleHoldTimerRunning() { return client_->idle_hold_timer_->running(); } - bool ConnectTimerRunning() { return client_->connect_timer_->running(); } + bool IdleHoldTimerRunning() { return sm_->IdleHoldTimerRunning(); } + bool ConnectTimerRunning() { return sm_->ConnectTimerRunning(); } EventManager evm_; SandeshClientMock *client_; + SandeshClientSMImpl *sm_; Timer *timer_; - Endpoint dummy_; }; typedef boost::function EvGen; @@ -343,7 +309,7 @@ struct EvGenComp { TEST_F(SandeshClientStateMachineTest, Matrix) { boost::asio::io_service::work work(*evm_.io_service()); - typedef std::map Transitions; + typedef std::map Transitions; #define CLIENT_SSM_TRANSITION(F, E) \ ((EvGen) boost::bind(&SandeshClientStateMachineTest_Matrix_Test::F, this), E) @@ -352,36 +318,37 @@ TEST_F(SandeshClientStateMachineTest, Matrix) { (SandeshSessionMock *) NULL), E) Transitions idle = map_list_of - CLIENT_SSM_TRANSITION(EvAdminUp, scm::CONNECT); + CLIENT_SSM_TRANSITION(EvAdminUp, SandeshClientSM::CONNECT); Transitions none = map_list_of - CLIENT_SSM_TRANSITION(EvStop, scm::IDLE); + CLIENT_SSM_TRANSITION(EvAdminDown, SandeshClientSM::IDLE); Transitions connect = map_list_of - CLIENT_SSM_TRANSITION(EvStop, scm::IDLE) - CLIENT_SSM_TRANSITION(EvConnectTimerExpired, scm::CONNECT) - CLIENT_SSM_TRANSITION(EvTcpConnected, scm::CLIENT_INIT) - CLIENT_SSM_TRANSITION(EvTcpConnectFail, scm::IDLE) - CLIENT_SSM_TRANSITION2(EvTcpClose, scm::CONNECT); + CLIENT_SSM_TRANSITION(EvAdminDown, SandeshClientSM::IDLE) + CLIENT_SSM_TRANSITION(EvConnectTimerExpired, SandeshClientSM::IDLE) + CLIENT_SSM_TRANSITION(EvTcpConnected, SandeshClientSM::CLIENT_INIT) + CLIENT_SSM_TRANSITION(EvTcpConnectFail, SandeshClientSM::IDLE) + CLIENT_SSM_TRANSITION2(EvTcpClose, SandeshClientSM::IDLE); Transitions client_init = map_list_of - CLIENT_SSM_TRANSITION2(EvTcpClose, scm::CONNECT) - CLIENT_SSM_TRANSITION2(EvSandeshMessageRecv, scm::CLIENT_INIT); + CLIENT_SSM_TRANSITION2(EvTcpClose, SandeshClientSM::IDLE) + CLIENT_SSM_TRANSITION2(EvSandeshMessageRecv, SandeshClientSM::CLIENT_INIT); Transitions matrix[] = - { idle, connect, none, client_init }; + { idle, none, connect, client_init }; - for (int k = scm::IDLE; k <= scm::CLIENT_INIT; k++) { - scm::SsmState i = static_cast (k); - // Ignore ESTABLISHED in SandeshClientStateMachine - if (i == scm::ESTABLISHED) { + for (int k = SandeshClientSM::IDLE; k <= SandeshClientSM::CLIENT_INIT; k++) { + SandeshClientSM::State i = static_cast(k); + // Ignore DISCONNECT and ESTABLISHED in SandeshClientSM + if (i == SandeshClientSM::ESTABLISHED || i == SandeshClientSM::DISCONNECT) { continue; } int count = 0; for (Transitions::iterator j = matrix[i].begin(); j != matrix[i].end(); j++) { - LOG(DEBUG, "Starting test " << count++ << " in state " << i - << " expecting " << j->second << " *********************"); + LOG(DEBUG, "Starting test " << count++ << " in state " << sm_->StateName(i) + << " expecting " << sm_->StateName(j->second)<< + " *********************"); GetToState(i); j->first(); RunToState(j->second); @@ -389,10 +356,9 @@ TEST_F(SandeshClientStateMachineTest, Matrix) { } } - class SandeshClientStateMachineConnectTest : public SandeshClientStateMachineTest { virtual void SetUp() { - GetToState(scm::CONNECT); + GetToState(SandeshClientSM::CONNECT); } virtual void TearDown() { @@ -401,36 +367,37 @@ class SandeshClientStateMachineConnectTest : public SandeshClientStateMachineTes // Old State: Connect // Event: EvTcpConnected -// New State: Established -// Timers: None should be running. +// New State: ClientInit +// Timers: Connect timer must be running again. // Messages: None. TEST_F(SandeshClientStateMachineConnectTest, TcpConnected) { EvTcpConnected(); - VerifyState(scm::CLIENT_INIT); - EXPECT_TRUE(!ConnectTimerRunning()); + VerifyState(SandeshClientSM::CLIENT_INIT); + EXPECT_TRUE(ConnectTimerRunning()); EXPECT_TRUE(client_->session() != NULL); } // Old State: Connect // Event: EvConnectTimerExpired -// New State: Active -// Timers: Connect timer must be running again. +// New State: Idle. +// Timers: Idle hold timer must be running. Connect timer should not be running. // Messages: None. TEST_F(SandeshClientStateMachineConnectTest, ConnectTimerExpired) { EvConnectTimerExpired(); - VerifyState(scm::CONNECT); - EXPECT_TRUE(ConnectTimerRunning()); - EXPECT_TRUE(client_->session() != NULL); + VerifyState(SandeshClientSM::IDLE); + EXPECT_TRUE(!ConnectTimerRunning()); + EXPECT_TRUE(IdleHoldTimerRunning()); + EXPECT_TRUE(client_->session() == NULL); } // Old State: Connect // Event: EvTcpConnectFail -// New State: Idle +// New State: Idle. // Timers: Idle hold timer must be running. Connect timer should not be running. // Messages: None. TEST_F(SandeshClientStateMachineConnectTest, TcpConnectFail) { EvTcpConnectFail(); - VerifyState(scm::IDLE); + VerifyState(SandeshClientSM::IDLE); EXPECT_TRUE(!ConnectTimerRunning()); EXPECT_TRUE(IdleHoldTimerRunning()); EXPECT_TRUE(client_->session() == NULL); @@ -438,7 +405,7 @@ TEST_F(SandeshClientStateMachineConnectTest, TcpConnectFail) { // Old State: Connect // Event: EvTcpConnected + EvConnectTimerExpired -// New State: ClientInit +// New State: Idle // Messages: None. // Other: The Connect timer has expired before it can be cancelled while // processing EvTcpConnected. @@ -447,15 +414,15 @@ TEST_F(SandeshClientStateMachineConnectTest, TcpConnectedThenConnectTimerExpired EvTcpConnected(); EvConnectTimerExpired(); TaskScheduler::GetInstance()->Start(); - VerifyState(scm::CLIENT_INIT); - EXPECT_TRUE(client_->session() != NULL); + VerifyState(SandeshClientSM::IDLE); + EXPECT_TRUE(client_->session() == NULL); EXPECT_TRUE(!ConnectTimerRunning()); - EXPECT_TRUE(!IdleHoldTimerRunning()); + EXPECT_TRUE(IdleHoldTimerRunning()); } // Old State: Connect // Event: EvConnectTimerExpired + EvTcpConnected -// New State: Connect +// New State: Idle // Messages: None. // Other: The Connect timer expired before we see EvTcpConnected, thus // the session would already have been deleted when we process @@ -465,16 +432,15 @@ TEST_F(SandeshClientStateMachineConnectTest, ConnectTimerExpiredThenTcpConnected EvConnectTimerExpired(); EvTcpConnected(); TaskScheduler::GetInstance()->Start(); - VerifyState(scm::CONNECT); - EXPECT_TRUE(client_->session() != NULL); - EXPECT_TRUE(ConnectTimerRunning()); - EXPECT_TRUE(!IdleHoldTimerRunning()); + VerifyState(SandeshClientSM::IDLE); + EXPECT_TRUE(client_->session() == NULL); + EXPECT_TRUE(!ConnectTimerRunning()); + EXPECT_TRUE(IdleHoldTimerRunning()); } -#if 0 class SandeshClientStateMachineEstablishedTest : public SandeshClientStateMachineTest { virtual void SetUp() { - GetToState(scm::CLIENT_INIT); + GetToState(SandeshClientSM::CLIENT_INIT); VerifyDirection(SandeshSessionMock::ACTIVE); } @@ -486,19 +452,10 @@ class SandeshClientStateMachineEstablishedTest : public SandeshClientStateMachin // Event: EvTcpClose // New State: Idle TEST_F(SandeshClientStateMachineEstablishedTest, TcpClose) { - TaskScheduler::GetInstance()->Stop(); EvTcpClose(); - TcpSession *session = client_->session(); - TaskScheduler::GetInstance()->Start(); - TASK_UTIL_EXPECT_EQ(true, !session->IsEstablished(), - "Wait for session to close"); - Endpoint endpoint; - TASK_UTIL_EXPECT_EQ(false, session->Connected(endpoint), - "Wait for session to close"); - VerifyState(scm::ESTABLISHED); - VerifyDirection(SandeshSessionMock::ACTIVE); + VerifyState(SandeshClientSM::IDLE); + EXPECT_TRUE(sm_->session() == NULL); } -#endif int main(int argc, char **argv) { LoggingInit(); diff --git a/library/cpp/test/sandesh_state_machine_test.cc b/library/cpp/test/sandesh_state_machine_test.cc index 3d4525f8..b427d11b 100644 --- a/library/cpp/test/sandesh_state_machine_test.cc +++ b/library/cpp/test/sandesh_state_machine_test.cc @@ -17,22 +17,18 @@ #include "io/event_manager.h" #include "testing/gunit.h" -#include -#include #include #include #include #include #include "sandesh_connection.h" -#include "sandesh_client.h" #include "sandesh_state_machine.h" +#include "sandesh_test_common.h" using namespace std; using namespace boost::assign; using namespace boost::posix_time; using boost::system::error_code; -using namespace contrail::sandesh::protocol; -using namespace contrail::sandesh::transport; typedef boost::asio::ip::tcp::endpoint Endpoint; @@ -134,53 +130,6 @@ class SandeshServerMock : public SandeshServer { SandeshSessionMock *old_session_; }; -const std::string FakeMessageSandeshBegin(""); -const std::string FakeMessageSandeshEnd(""); - -static void CreateFakeMessage(uint8_t *data, size_t length) { - size_t offset = 0; - SandeshHeader header; - // Populate the header - header.set_Namespace("Test"); - header.set_Timestamp(123456); - header.set_Module("SandeshStateMachineTest"); - header.set_Source("TestMachine"); - header.set_Context(""); - header.set_SequenceNum(0); - header.set_VersionSig(0); - header.set_Type(SandeshType::SYSTEM); - header.set_Hints(0); - header.set_Level(SandeshLevel::SYS_DEBUG); - header.set_Category("SSM"); - boost::shared_ptr btrans = - boost::shared_ptr( - new TMemoryBuffer(512)); - boost::shared_ptr prot = - boost::shared_ptr( - new TXMLProtocol(btrans)); - // Write the sandesh header - int ret = header.write(prot); - EXPECT_GT(ret, 0); - EXPECT_GT(length, offset + ret); - // Get the buffer - uint8_t *hbuffer; - uint32_t hlen; - btrans->getBuffer(&hbuffer, &hlen); - EXPECT_EQ(hlen, ret); - memcpy(data + offset, hbuffer, hlen); - offset += hlen; - EXPECT_GT(length, offset + FakeMessageSandeshBegin.size()); - memcpy(data + offset, FakeMessageSandeshBegin.c_str(), - FakeMessageSandeshBegin.size()); - offset += FakeMessageSandeshBegin.size(); - memset(data + offset, '0', length - offset - FakeMessageSandeshEnd.size()); - offset += length - offset - FakeMessageSandeshEnd.size(); - memcpy(data + offset, FakeMessageSandeshEnd.c_str(), - FakeMessageSandeshEnd.size()); - offset += FakeMessageSandeshEnd.size(); - EXPECT_EQ(offset, length); -} - class SandeshServerStateMachineTest : public ::testing::Test { protected: SandeshServerStateMachineTest() : diff --git a/library/cpp/test/sandesh_test_common.cc b/library/cpp/test/sandesh_test_common.cc new file mode 100644 index 00000000..86408efb --- /dev/null +++ b/library/cpp/test/sandesh_test_common.cc @@ -0,0 +1,64 @@ +// +// Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. +// + +// +// sandesh_test_common.cc +// + +#include "testing/gunit.h" + +#include +#include +#include +#include + +using namespace contrail::sandesh::protocol; +using namespace contrail::sandesh::transport; + +static const std::string FakeMessageSandeshBegin(""); +static const std::string FakeMessageSandeshEnd(""); + +void CreateFakeMessage(uint8_t *data, size_t length) { + size_t offset = 0; + SandeshHeader header; + // Populate the header + header.set_Namespace("Test"); + header.set_Timestamp(123456); + header.set_Module("SandeshStateMachineTest"); + header.set_Source("TestMachine"); + header.set_Context(""); + header.set_SequenceNum(0); + header.set_VersionSig(0); + header.set_Type(SandeshType::SYSTEM); + header.set_Hints(0); + header.set_Level(SandeshLevel::SYS_DEBUG); + header.set_Category("SSM"); + boost::shared_ptr btrans = + boost::shared_ptr( + new TMemoryBuffer(512)); + boost::shared_ptr prot = + boost::shared_ptr( + new TXMLProtocol(btrans)); + // Write the sandesh header + int ret = header.write(prot); + EXPECT_GT(ret, 0); + EXPECT_GT(length, offset + ret); + // Get the buffer + uint8_t *hbuffer; + uint32_t hlen; + btrans->getBuffer(&hbuffer, &hlen); + EXPECT_EQ(hlen, ret); + memcpy(data + offset, hbuffer, hlen); + offset += hlen; + EXPECT_GT(length, offset + FakeMessageSandeshBegin.size()); + memcpy(data + offset, FakeMessageSandeshBegin.c_str(), + FakeMessageSandeshBegin.size()); + offset += FakeMessageSandeshBegin.size(); + memset(data + offset, '0', length - offset - FakeMessageSandeshEnd.size()); + offset += length - offset - FakeMessageSandeshEnd.size(); + memcpy(data + offset, FakeMessageSandeshEnd.c_str(), + FakeMessageSandeshEnd.size()); + offset += FakeMessageSandeshEnd.size(); + EXPECT_EQ(offset, length); +} diff --git a/library/cpp/test/sandesh_test_common.h b/library/cpp/test/sandesh_test_common.h new file mode 100644 index 00000000..8a7802db --- /dev/null +++ b/library/cpp/test/sandesh_test_common.h @@ -0,0 +1,10 @@ +// +// Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. +// + +#ifndef SANDESH_LIBRARY_CPP_TEST_SANDESH_TEST_COMMON_H_ +#define SANDESH_LIBRARY_CPP_TEST_SANDESH_TEST_COMMON_H_ + +void CreateFakeMessage(uint8_t *data, size_t length); + +#endif // SANDESH_LIBRARY_CPP_TEST_SANDESH_TEST_COMMON_H_