Skip to content

Commit

Permalink
Add integration test for BGPaaS functionality
Browse files Browse the repository at this point in the history
o Apply BGPaaS server and BGPaaS client configurations to DUT
o Use other BgpServer to peer as BGPaaS clients
o Play with source-port and cheat production code to infer connections coming
  as if from BGPaaS client
o Verify that peers come up and stay established
o Verify that cleanup happens correctly
o TODO: Add more integration tests involving mock agents, with BGPaaS routes
  that resolve over routes learned from mock XMPP agents

Change-Id: Iaeddd1658f187dd735585bc094b233bcd940dd57
Partial-Bug: #1518047
  • Loading branch information
ananth-at-camphor-networks committed Nov 3, 2016
1 parent a638f7c commit a459ebc
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/bgp/bgp_server.h
Expand Up @@ -75,7 +75,7 @@ class BgpServer {
BgpPeer *FindPeer(const std::string &name);
void InsertPeer(TcpSession::Endpoint remote, BgpPeer *peer);
void RemovePeer(TcpSession::Endpoint remote, BgpPeer *peer);
BgpPeer *FindPeer(TcpSession::Endpoint remote) const;
virtual BgpPeer *FindPeer(TcpSession::Endpoint remote) const;
BgpPeer *FindNextPeer(
TcpSession::Endpoint remote = TcpSession::Endpoint()) const;

Expand Down
4 changes: 4 additions & 0 deletions src/bgp/test/SConscript
Expand Up @@ -146,6 +146,9 @@ bgp_authentication_test = env.UnitTest('bgp_authentication_test',
['bgp_authentication_test.cc'])
env.Alias('src/bgp:bgp_authentication_test', bgp_authentication_test)

bgp_bgpaas_test = env.UnitTest('bgp_bgpaas_test', ['bgp_bgpaas_test.cc'])
env.Alias('src/bgp:bgp_bgpaas_test', bgp_bgpaas_test)

bgp_condition_listener_test = env.UnitTest('bgp_condition_listener_test',
['bgp_condition_listener_test.cc'])
env.Alias('src/bgp:bgp_condition_listener_test', bgp_condition_listener_test)
Expand Down Expand Up @@ -565,6 +568,7 @@ yaml_test_env.Alias('bgp:bgp_yaml_config_manager_test',
test_suite = [
bgp_attr_test,
bgp_authentication_test,
bgp_bgpaas_test,
bgp_condition_listener_test,
bgp_config_listener_test,
bgp_ifmap_config_manager_test,
Expand Down
257 changes: 257 additions & 0 deletions src/bgp/test/bgp_bgpaas_test.cc
@@ -0,0 +1,257 @@
/*
* Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
*/

#include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp>

#include "base/task_annotations.h"
#include "bgp/bgp_config_parser.h"
#include "bgp/bgp_factory.h"
#include "bgp/bgp_membership.h"
#include "bgp/bgp_sandesh.h"
#include "bgp/bgp_session_manager.h"
#include "bgp/inet/inet_table.h"
#include "bgp/test/bgp_server_test_util.h"
#include "control-node/control_node.h"
#include "io/test/event_manager_test.h"

using namespace std;

static string clientsConfigStr =
"<?xml version='1.0' encoding='utf-8'?> \n"
"<config> \n"
" <bgp-router name='bgpaas-server'> \n"
" <address>127.0.0.1</address> \n"
" <autonomous-system>64512</autonomous-system> \n"
" <identifier>192.168.1.1</identifier> \n"
" <port>__server_port__</port> \n"
" <session to='vm1'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" <session to='vm2'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" </bgp-router> \n"
" <bgp-router name='vm1'> \n"
" <address>127.0.0.1</address> \n"
" <autonomous-system>65001</autonomous-system> \n"
" <port>__vm1_port__</port> \n"
" <identifier>10.0.0.1</identifier> \n"
" <session to='bgpaas-server'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" </bgp-router> \n"
" <bgp-router name='vm2'> \n"
" <address>127.0.0.1</address> \n"
" <autonomous-system>65002</autonomous-system> \n"
" <port>__vm2_port__</port> \n"
" <identifier>10.0.0.2</identifier> \n"
" <session to='bgpaas-server'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" </bgp-router> \n"
"</config> \n"
;

static string serverConfigStr =
"<?xml version='1.0' encoding='utf-8'?> \n"
"<config> \n"
" <bgp-router name='local'> \n"
" <address>127.0.0.1</address> \n"
" <autonomous-system>64512</autonomous-system> \n"
" <identifier>192.168.1.1</identifier> \n"
" <port>__server_port__</port> \n"
" </bgp-router> \n"
" <routing-instance name='test'> \n"
" <vrf-target>target:64512:1</vrf-target> \n"
" <bgp-router name='bgpaas-server'> \n"
" <router-type>bgpaas-server</router-type> \n"
" <autonomous-system>64512</autonomous-system> \n"
" <port>__server_port__</port> \n"
" <session to='vm1'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" <session to='vm2'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" </bgp-router> \n"
" <bgp-router name='vm1'> \n"
" <router-type>bgpaas-client</router-type> \n"
" <autonomous-system>65001</autonomous-system> \n"
" <address>127.0.0.1</address> \n"
" <source-port>11024</source-port> \n"
" <session to='bgpaas-server'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" </bgp-router> \n"
" <bgp-router name='vm2'> \n"
" <router-type>bgpaas-client</router-type> \n"
" <autonomous-system>65002</autonomous-system> \n"
" <address>127.0.0.1</address> \n"
" <source-port>11025</source-port> \n"
" <session to='bgpaas-server'> \n"
" <family-attributes> \n"
" <address-family>inet</address-family> \n"
" </family-attributes> \n"
" <family-attributes> \n"
" <address-family>inet6</address-family> \n"
" </family-attributes> \n"
" </session> \n"
" </bgp-router> \n"
" </routing-instance> \n"
"</config> \n"
;

class BGPaaSTest : public ::testing::Test {
protected:
BGPaaSTest() :
server_session_manager_(NULL), vm1_session_manager_(NULL),
vm2_session_manager_(NULL) {
}

virtual void SetUp() {
evm_.reset(new EventManager());
server_.reset(new BgpServerTest(evm_.get(), "local"));
vm1_.reset(new BgpServerTest(evm_.get(), "vm1"));
vm2_.reset(new BgpServerTest(evm_.get(), "vm2"));
thread_.reset(new ServerThread(evm_.get()));

server_session_manager_ = server_->session_manager();
server_session_manager_->Initialize(0);
BGP_DEBUG_UT("Created server at port: " <<
server_session_manager_->GetPort());

vm1_session_manager_ = vm1_->session_manager();
vm1_session_manager_->Initialize(0);
BGP_DEBUG_UT("Created server at port: " <<
vm1_session_manager_->GetPort());

vm2_session_manager_ = vm2_->session_manager();
vm2_session_manager_->Initialize(0);
BGP_DEBUG_UT("Created server at port: " <<
vm2_session_manager_->GetPort());
thread_->Start();
BgpPeerTest::verbose_name(true);
}

virtual void TearDown() {
task_util::WaitForIdle();
server_->Shutdown();
vm1_->Shutdown();
task_util::WaitForIdle();
vm2_->Shutdown();
task_util::WaitForIdle();
TASK_UTIL_EXPECT_EQ(0, TcpServerManager::GetServerCount());

evm_->Shutdown();
if (thread_.get() != NULL)
thread_->Join();
BgpPeerTest::verbose_name(false);
}

BgpPeerTest *WaitForPeerToComeUp(BgpServerTest *server,
const string &peerName) {
string u = BgpConfigParser::session_uuid("bgpaas-server", peerName, 1);
TASK_UTIL_EXPECT_NE(static_cast<BgpPeerTest *>(NULL),
dynamic_cast<BgpPeerTest *>(
server->FindPeerByUuid(BgpConfigManager::kMasterInstance, u)));
BgpPeerTest *peer = dynamic_cast<BgpPeerTest *>(
server->FindPeerByUuid(BgpConfigManager::kMasterInstance, u));
BGP_WAIT_FOR_PEER_STATE(peer, StateMachine::ESTABLISHED);
return peer;
}

auto_ptr<EventManager> evm_;
auto_ptr<ServerThread> thread_;
auto_ptr<BgpServerTest> server_;
auto_ptr<BgpServerTest> vm1_;
auto_ptr<BgpServerTest> vm2_;
BgpSessionManager *server_session_manager_;
BgpSessionManager *vm1_session_manager_;
BgpSessionManager *vm2_session_manager_;
};

TEST_F(BGPaaSTest, Basic) {
server_->set_peer_lookup_disable(true);
vm1_->set_source_port(11024);
vm2_->set_source_port(11025);
boost::replace_all(serverConfigStr, "__server_port__",
boost::lexical_cast<string>(server_session_manager_->GetPort()));
boost::replace_all(clientsConfigStr, "__server_port__",
boost::lexical_cast<string>(server_session_manager_->GetPort()));
boost::replace_all(clientsConfigStr, "__vm1_port__",
boost::lexical_cast<string>(vm1_session_manager_->GetPort()));
boost::replace_all(clientsConfigStr, "__vm2_port__",
boost::lexical_cast<string>(vm2_session_manager_->GetPort()));
cout << serverConfigStr << endl << endl << endl << endl;
cout << clientsConfigStr << endl;
vm1_->Configure(clientsConfigStr);
vm2_->Configure(clientsConfigStr);
task_util::WaitForIdle();

server_->Configure(serverConfigStr);
WaitForPeerToComeUp(vm1_.get(), "vm1");
WaitForPeerToComeUp(vm2_.get(), "vm2");
}

class TestEnvironment : public ::testing::Environment {
virtual ~TestEnvironment() { }
};

static void SetUp() {
BgpServer::Initialize();
ControlNode::SetDefaultSchedulingPolicy();
BgpServerTest::GlobalSetUp();
}

static void TearDown() {
BgpServer::Terminate();
TaskScheduler *scheduler = TaskScheduler::GetInstance();
scheduler->Terminate();
}

int main(int argc, char **argv) {
bgp_log_test::init();
::testing::InitGoogleTest(&argc, argv);
::testing::AddGlobalTestEnvironment(new TestEnvironment());
SetUp();
int result = RUN_ALL_TESTS();
TearDown();
return result;
}
37 changes: 35 additions & 2 deletions src/bgp/test/bgp_server_test_util.cc
Expand Up @@ -47,6 +47,8 @@ BgpServerTest::BgpServerTest(EventManager *evm, const string &localname,
config_manager->Initialize(config_db_.get(), config_graph_.get(),
localname);
cleanup_config_ = false;
source_port_ = 0;
peer_lookup_disable_ = false;
rtarget_group_mgr_->Initialize();
}

Expand All @@ -58,6 +60,8 @@ BgpServerTest::BgpServerTest(EventManager *evm, const string &localname)
config_graph_(new DBGraph()) {
ConcurrencyScope scope("bgp::Config");
cleanup_config_ = true;
source_port_ = 0;
peer_lookup_disable_ = false;
IFMapLinkTable_Init(config_db_.get(), config_graph_.get());
vnc_cfg_Server_ModuleInit(config_db_.get(), config_graph_.get());
bgp_schema_Server_ModuleInit(config_db_.get(), config_graph_.get());
Expand Down Expand Up @@ -276,15 +280,31 @@ void BgpPeerTest::BindLocalEndpoint(BgpSession *session) {
BgpPeerKey peer_key;
peer_key.endpoint.address(
ip::address::from_string("127.0.0.1", err));
peer_key.endpoint.port(server()->session_manager()->GetPort());

// Check if we need to map to source-port only lookup (for BGPaas Clients)
local_port = static_cast<BgpServerTest *>(server())->source_port();
if (local_port) {

// Place the configured source-port in the map, as the fake BGPaaS
// clients do not actually send packets with configured source-port
// as local-port.
peer_key.endpoint.port(local_port);
peer_key.endpoint.address(Ip4Address());
local_endpoint.address(Ip4Address());
} else {

// Use server-port as the value (which is used later to find the proper
// bgp-peer in configuration.
peer_key.endpoint.port(server()->session_manager()->GetPort());
}

if (config_) {
if (!config_->uuid().empty()) {
boost::uuids::string_generator gen;
peer_key.uuid = gen(config_->uuid());
} else {
boost::uuids::nil_generator nil;
peer_key.uuid == nil();
peer_key.uuid = nil();
}
tbb::mutex::scoped_lock lock(peer_connect_map_mutex_);
peer_connect_map_[local_endpoint] = peer_key;
Expand Down Expand Up @@ -328,6 +348,11 @@ void PeerManagerTest::DestroyIPeer(IPeer *ipeer) {
//
BgpPeer *PeerManagerTest::PeerLookup(
TcpSession::Endpoint remote_endpoint) const {

// Check if port-based peer lookup is disabled.
if (static_cast<BgpServerTest *>(server())->peer_lookup_disable())
return PeerManager::PeerLookup(remote_endpoint);

BgpPeerKey peer_key;
bool present;

Expand Down Expand Up @@ -362,6 +387,14 @@ BgpPeer *PeerManagerTest::PeerLookup(
return loc->second;
}

// Find peer based on remote-endpoint port (BGPaaS client)
BgpPeer *BgpServerTest::FindPeer(TcpSession::Endpoint remote_endpoint) const {
tbb::mutex::scoped_lock lock(peer_connect_map_mutex_);
if (peer_connect_map_.count(remote_endpoint) > 0)
remote_endpoint = peer_connect_map_.at(remote_endpoint).endpoint;
return BgpServer::FindPeer(remote_endpoint);
}

BgpInstanceConfigTest *BgpTestUtil::CreateBgpInstanceConfig(
const string &name,
const string import_targets, const string export_targets,
Expand Down
7 changes: 7 additions & 0 deletions src/bgp/test/bgp_server_test_util.h
Expand Up @@ -214,6 +214,7 @@ class BgpServerTest : public BgpServer {
const std::string &uuid);
BgpPeer *FindPeer(const char *routing_instance,
const std::string &peername);
BgpPeer *FindPeer(TcpSession::Endpoint remote) const;
BgpPeer *FindMatchingPeer(const std::string &routing_instance,
const std::string &name);
void DisableAllPeers();
Expand All @@ -235,6 +236,10 @@ class BgpServerTest : public BgpServer {
}

virtual std::string ToString() const;
uint16_t source_port() const { return source_port_; }
void set_source_port(uint16_t source_port) { source_port_ = source_port; }
bool peer_lookup_disable() const { return peer_lookup_disable_; }
void set_peer_lookup_disable(bool flag) { peer_lookup_disable_ = flag; }

private:
void PostShutdown();
Expand All @@ -243,6 +248,8 @@ class BgpServerTest : public BgpServer {
boost::scoped_ptr<DB> config_db_;
boost::scoped_ptr<DBGraph> config_graph_;
bool cleanup_config_;
uint16_t source_port_;
bool peer_lookup_disable_;
};

typedef boost::shared_ptr<BgpServerTest> BgpServerTestPtr;
Expand Down

0 comments on commit a459ebc

Please sign in to comment.