From 1daccd58653d7fbea482aacf222f1bafae384800 Mon Sep 17 00:00:00 2001 From: Nischal Sheth Date: Tue, 18 Aug 2015 08:53:41 -0700 Subject: [PATCH] Support pagination of output for rtarget group introspect Limit the maximum number of entries displayed on a single page. A next_batch link is generated if there are more entries to be displayed. Also limit maximum number of entries examined in one invocation of the callback routine. This comes into play when there is a search string specified and many entries don't match it. A partial page is saved in user-allocated data and the next invocation of callback appends to it. This is repeated till there's a full page or there are no more entries in the table. Following changes are implemented: - Move introspect commands to bgp_peer.sandesh - Move code from rtarget_group_mgr.cc to bgp_show_rtarget_group.cc - Use class template BgpShowHandler to avoid code duplication - Implement iteration limit to avoid hogging CPU from introspect - Make some typedefs in RTargetGroupMgr private - Add unit tests to cover combinations of page and iteration limits Change-Id: I526b983b03024d248f5220d4692b0ef5880dcb9a Closes-Bug: 1485726 --- src/bgp/SConscript | 1 + src/bgp/bgp_peer.sandesh | 43 ++ src/bgp/bgp_peer_internal.sandesh | 12 + src/bgp/bgp_server.h | 3 + src/bgp/bgp_show_rtarget_group.cc | 307 ++++++++ src/bgp/routing-instance/SConscript | 1 - src/bgp/routing-instance/routing_instance.cc | 2 +- src/bgp/routing-instance/rtarget_group.cc | 12 +- src/bgp/routing-instance/rtarget_group.h | 5 +- .../routing-instance/rtarget_group.sandesh | 39 - src/bgp/routing-instance/rtarget_group_mgr.cc | 113 --- src/bgp/routing-instance/rtarget_group_mgr.h | 22 +- src/bgp/rtarget/rtarget_address.cc | 3 +- src/bgp/test/SConscript | 6 + src/bgp/test/bgp_show_rtarget_group_test.cc | 676 ++++++++++++++++++ src/bgp/test/bgp_xmpp_rtarget_test.cc | 11 +- 16 files changed, 1079 insertions(+), 177 deletions(-) create mode 100644 src/bgp/bgp_show_rtarget_group.cc delete mode 100644 src/bgp/routing-instance/rtarget_group.sandesh create mode 100644 src/bgp/test/bgp_show_rtarget_group_test.cc diff --git a/src/bgp/SConscript b/src/bgp/SConscript index 9c6c354e2f9..01b740f3c63 100644 --- a/src/bgp/SConscript +++ b/src/bgp/SConscript @@ -65,6 +65,7 @@ libbgp = env.Library('bgp', 'bgp_show_route.cc', 'bgp_show_route_summary.cc', 'bgp_show_routing_instance.cc', + 'bgp_show_rtarget_group.cc', 'bgp_table.cc', 'bgp_update.cc', 'bgp_update_monitor.cc', diff --git a/src/bgp/bgp_peer.sandesh b/src/bgp/bgp_peer.sandesh index 188586fffbe..d303db368d4 100644 --- a/src/bgp/bgp_peer.sandesh +++ b/src/bgp/bgp_peer.sandesh @@ -262,6 +262,49 @@ request sandesh ShowRoutingInstanceSummaryReq { 1: string search_string; } +struct ShowRtGroupMemberTableList { + 1: string family; + 2: list tables; +} + +struct ShowRtGroupInfo { + 1: string rtarget (link="ShowRtGroupReq"); + 2: list import_members; + 3: list export_members; + 4: optional list peers_interested; + 5: optional list dep_route; +} + +response sandesh ShowRtGroupResp { + 1: list rtgroup_list; + 2: optional string next_batch (link="ShowRtGroupReqIterate", + link_title="next_batch"); +} + +request sandesh ShowRtGroupReq { + 1: string search_string; +} + +response sandesh ShowRtGroupSummaryResp { + 1: list rtgroup_list; + 2: optional string next_batch (link="ShowRtGroupSummaryReqIterate", + link_title="next_batch"); +} + +request sandesh ShowRtGroupSummaryReq { + 1: string search_string; +} + +response sandesh ShowRtGroupPeerResp { + 1: list rtgroup_list; + 2: optional string next_batch (link="ShowRtGroupPeerReqIterate", + link_title="next_batch"); +} + +request sandesh ShowRtGroupPeerReq { + 1: string search_string; +} + struct ShowEvpnTable { 1: string name (link="ShowRouteReq"); 2: u64 mac_routes; diff --git a/src/bgp/bgp_peer_internal.sandesh b/src/bgp/bgp_peer_internal.sandesh index 58773473b30..33610ea052f 100644 --- a/src/bgp/bgp_peer_internal.sandesh +++ b/src/bgp/bgp_peer_internal.sandesh @@ -50,6 +50,18 @@ request sandesh ShowRoutingInstanceSummaryReqIterate { 1: string iterate_info; } +request sandesh ShowRtGroupReqIterate { + 1: string iterate_info; +} + +request sandesh ShowRtGroupSummaryReqIterate { + 1: string iterate_info; +} + +request sandesh ShowRtGroupPeerReqIterate { + 1: string iterate_info; +} + request sandesh ShowEvpnTableReqIterate { 1: string iterate_info; } diff --git a/src/bgp/bgp_server.h b/src/bgp/bgp_server.h index 3f868f22e2d..6af03f9d13a 100644 --- a/src/bgp/bgp_server.h +++ b/src/bgp/bgp_server.h @@ -78,6 +78,9 @@ class BgpServer { return inst_mgr_.get(); } RTargetGroupMgr *rtarget_group_mgr() { return rtarget_group_mgr_.get(); } + const RTargetGroupMgr *rtarget_group_mgr() const { + return rtarget_group_mgr_.get(); + } BgpConditionListener *condition_listener(Address::Family family) { if (family == Address::INET) return inet_condition_listener_.get(); diff --git a/src/bgp/bgp_show_rtarget_group.cc b/src/bgp/bgp_show_rtarget_group.cc new file mode 100644 index 00000000000..7c7e61b0ba6 --- /dev/null +++ b/src/bgp/bgp_show_rtarget_group.cc @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +#include "bgp/bgp_show_handler.h" + +#include + +#include "bgp/bgp_peer_internal_types.h" +#include "bgp/bgp_peer_types.h" +#include "bgp/bgp_server.h" +#include "bgp/routing-instance/rtarget_group.h" +#include "bgp/routing-instance/rtarget_group_mgr.h" + +using std::string; +using std::vector; + +// +// Fill in information for list of rtarget groups. +// +// Allows regular, summary and peer introspect to share code. +// Assumes that search_string is the peer name if match_peer is true. +// +static bool FillRtGroupInfoList(const BgpSandeshContext *bsc, + bool summary, bool match_peer, uint32_t page_limit, uint32_t iter_limit, + const string &start_rtarget_str, const string &search_string, + vector *srtg_list, string *next_rtarget_str) { + RouteTarget rtarget; + + // Bail if start_rtarget_str is bad. + if (!start_rtarget_str.empty()) { + rtarget = RouteTarget::FromString(start_rtarget_str); + if (rtarget.IsNull()) + return true; + } + + // Bail if there's no peer specified when doing a peer introspect. + if (match_peer && search_string.empty()) + return true; + + const RTargetGroupMgr *rtgroup_mgr = bsc->bgp_server->rtarget_group_mgr(); + RTargetGroupMgr::const_iterator it = rtgroup_mgr->lower_bound(rtarget); + for (uint32_t iter_count = 0; it != rtgroup_mgr->end(); + ++it, ++iter_count) { + const RtGroup *rtgroup = it->second; + if (!match_peer && !search_string.empty() && + (rtgroup->ToString().find(search_string) == string::npos)) { + continue; + } + ShowRtGroupInfo srtg; + if (match_peer) { + if (!rtgroup->HasInterestedPeer(search_string)) + continue; + rtgroup->FillShowPeerInfo(&srtg); + } else if (summary) { + rtgroup->FillShowSummaryInfo(&srtg); + } else { + rtgroup->FillShowInfo(&srtg); + } + srtg_list->push_back(srtg); + if (srtg_list->size() >= page_limit) + break; + if (iter_count >= iter_limit) + break; + } + + // All done if we've looked at all rtarget groups. + if (it == rtgroup_mgr->end() || ++it == rtgroup_mgr->end()) + return true; + + // Return true if we've reached the page limit, false if we've reached the + // iteration limit. + bool done = srtg_list->size() >= page_limit; + *next_rtarget_str = it->second->ToString(); + return done; +} + +// +// Specialization of BgpShowHandler<>::CallbackCommon for regular introspect. +// +template <> +bool BgpShowHandler::CallbackCommon( + const BgpSandeshContext *bsc, Data *data) { + uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; + uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; + string next_rtarget_str; + bool done = FillRtGroupInfoList(bsc, false, false, page_limit, iter_limit, + data->next_entry, data->search_string, &data->show_list, + &next_rtarget_str); + if (!next_rtarget_str.empty()) + SaveContextToData(next_rtarget_str, done, data); + return done; +} + +// +// Specialization of BgpShowHandler<>::FillShowList for regular introspect. +// +template <> +void BgpShowHandler::FillShowList( + ShowRtGroupResp *resp, + const vector &show_list) { + resp->set_rtgroup_list(show_list); +} + +// +// Specialization of BgpShowHandler<>::CallbackCommon for summary introspect. +// +template <> +bool BgpShowHandler::CallbackCommon( + const BgpSandeshContext *bsc, Data *data) { + uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; + uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; + string next_rtarget_str; + bool done = FillRtGroupInfoList(bsc, true, false, page_limit, iter_limit, + data->next_entry, data->search_string, &data->show_list, + &next_rtarget_str); + if (!next_rtarget_str.empty()) + SaveContextToData(next_rtarget_str, done, data); + return done; +} + +// +// Specialization of BgpShowHandler<>::FillShowList for summary introspect. +// +template <> +void BgpShowHandler::FillShowList( + ShowRtGroupSummaryResp *resp, + const vector &show_list) { + resp->set_rtgroup_list(show_list); +} + +// +// Specialization of BgpShowHandler<>::CallbackCommon for peer introspect. +// +template <> +bool BgpShowHandler::CallbackCommon( + const BgpSandeshContext *bsc, Data *data) { + uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; + uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; + string next_rtarget_str; + bool done = FillRtGroupInfoList(bsc, false, true, page_limit, iter_limit, + data->next_entry, data->search_string, &data->show_list, + &next_rtarget_str); + if (!next_rtarget_str.empty()) + SaveContextToData(next_rtarget_str, done, data); + return done; +} + +// +// Specialization of BgpShowHandler<>::FillShowList for peer introspect. +// +template <> +void BgpShowHandler::FillShowList( + ShowRtGroupPeerResp *resp, + const vector &show_list) { + resp->set_rtgroup_list(show_list); +} + +// +// Handler for ShowRtGroupReq. +// +void ShowRtGroupReq::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRtGroupReq, + ShowRtGroupReqIterate, + ShowRtGroupResp, + ShowRtGroupInfo>::Callback, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRtGroupReq, + ShowRtGroupReqIterate, + ShowRtGroupResp, + ShowRtGroupInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowRtGroupReqIterate. +// +void ShowRtGroupReqIterate::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRtGroupReq, + ShowRtGroupReqIterate, + ShowRtGroupResp, + ShowRtGroupInfo>::CallbackIterate, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRtGroupReq, + ShowRtGroupReqIterate, + ShowRtGroupResp, + ShowRtGroupInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowRtGroupSummaryReq. +// +void ShowRtGroupSummaryReq::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRtGroupSummaryReq, + ShowRtGroupSummaryReqIterate, + ShowRtGroupSummaryResp, + ShowRtGroupInfo>::Callback, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRtGroupSummaryReq, + ShowRtGroupSummaryReqIterate, + ShowRtGroupSummaryResp, + ShowRtGroupInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowRtGroupSummaryReqIterate. +// +void ShowRtGroupSummaryReqIterate::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRtGroupSummaryReq, + ShowRtGroupSummaryReqIterate, + ShowRtGroupSummaryResp, + ShowRtGroupInfo>::CallbackIterate, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRtGroupSummaryReq, + ShowRtGroupSummaryReqIterate, + ShowRtGroupSummaryResp, + ShowRtGroupInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowRtGroupPeerReq. +// +void ShowRtGroupPeerReq::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRtGroupPeerReq, + ShowRtGroupPeerReqIterate, + ShowRtGroupPeerResp, + ShowRtGroupInfo>::Callback, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRtGroupPeerReq, + ShowRtGroupPeerReqIterate, + ShowRtGroupPeerResp, + ShowRtGroupInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowRtGroupPeerReqIterate. +// +void ShowRtGroupPeerReqIterate::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::RTFilter"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRtGroupPeerReq, + ShowRtGroupPeerReqIterate, + ShowRtGroupPeerResp, + ShowRtGroupInfo>::CallbackIterate, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRtGroupPeerReq, + ShowRtGroupPeerReqIterate, + ShowRtGroupPeerResp, + ShowRtGroupInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} diff --git a/src/bgp/routing-instance/SConscript b/src/bgp/routing-instance/SConscript index 59e113aefc0..a87e220260e 100644 --- a/src/bgp/routing-instance/SConscript +++ b/src/bgp/routing-instance/SConscript @@ -16,7 +16,6 @@ env.Append(CPPPATH = [env['TOP'] + '/io']) SandeshGenFiles = env.SandeshGenCpp('routing_instance_analytics.sandesh') SandeshGenFiles += env.SandeshGenCpp('service_chaining.sandesh') SandeshGenFiles += env.SandeshGenCpp('static_route.sandesh') -SandeshGenFiles += env.SandeshGenCpp('rtarget_group.sandesh') SandeshGenSrcs = env.ExtractCpp(SandeshGenFiles) librouting_instance = env.Library('routing_instance', SandeshGenSrcs + diff --git a/src/bgp/routing-instance/routing_instance.cc b/src/bgp/routing-instance/routing_instance.cc index a7532a1b0cf..f2d4389856d 100644 --- a/src/bgp/routing-instance/routing_instance.cc +++ b/src/bgp/routing-instance/routing_instance.cc @@ -780,7 +780,7 @@ BgpTable *RoutingInstance::VpnTableCreate(Address::Family vpn_family) { AddTable(table); RTINSTANCE_LOG_TABLE(Create, this, table, SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL); - assert(server_->rtarget_group_mgr()->GetRtGroupMap().empty()); + assert(server_->rtarget_group_mgr()->empty()); RoutePathReplicator *replicator = server_->replicator(vpn_family); replicator->Initialize(); return table; diff --git a/src/bgp/routing-instance/rtarget_group.cc b/src/bgp/routing-instance/rtarget_group.cc index 4438ab12b8c..6c4b40ee1bb 100644 --- a/src/bgp/routing-instance/rtarget_group.cc +++ b/src/bgp/routing-instance/rtarget_group.cc @@ -7,8 +7,8 @@ #include #include +#include "bgp/bgp_peer_types.h" #include "bgp/bgp_route.h" -#include "bgp/routing-instance/rtarget_group_types.h" #include "bgp/rtarget/rtarget_route.h" using std::pair; @@ -174,9 +174,9 @@ bool RtGroup::HasInterestedPeer(const string &name) const { } void RtGroup::FillMemberTables(const RtGroupMembers &rt_members, - vector *member_list) const { + vector *member_list) const { BOOST_FOREACH(const RtGroupMembers::value_type &rt_tables, rt_members) { - MemberTableList member; + ShowRtGroupMemberTableList member; vector table_names; BOOST_FOREACH(BgpTable *table, rt_tables.second) { table_names.push_back(table->name()); @@ -205,12 +205,12 @@ void RtGroup::FillDependentRoutes(vector *rtlist) const { void RtGroup::FillShowInfoCommon(ShowRtGroupInfo *info, bool fill_peers, bool fill_routes) const { - info->set_rtarget(rt_.ToString()); + info->set_rtarget(ToString()); - vector import_members; + vector import_members; FillMemberTables(import_, &import_members); info->set_import_members(import_members); - vector export_members; + vector export_members; FillMemberTables(export_, &export_members); info->set_export_members(export_members); diff --git a/src/bgp/routing-instance/rtarget_group.h b/src/bgp/routing-instance/rtarget_group.h index 3bcf7cab1c9..f8ebc5683a3 100644 --- a/src/bgp/routing-instance/rtarget_group.h +++ b/src/bgp/routing-instance/rtarget_group.h @@ -15,7 +15,7 @@ class BgpRoute; class RTargetRoute; -class MemberTableList; +class ShowRtGroupMemberTableList; class ShowRtGroupInfo; class RtGroupInterestedPeerSet : public BitSet { @@ -65,6 +65,7 @@ class RtGroup { explicit RtGroup(const RouteTarget &rt); const RouteTarget &rt(); + std::string ToString() const { return rt_.ToString(); } bool MayDelete() const; const RtGroupMemberList GetImportTables(Address::Family family) const; @@ -95,7 +96,7 @@ class RtGroup { private: void FillMemberTables(const RtGroupMembers &rt_members, - std::vector *member_list) const; + std::vector *member_list) const; void FillInterestedPeers(std::vector *interested_peers) const; void FillDependentRoutes(std::vector *rtlist) const; void FillShowInfoCommon( diff --git a/src/bgp/routing-instance/rtarget_group.sandesh b/src/bgp/routing-instance/rtarget_group.sandesh deleted file mode 100644 index 58cbddeafde..00000000000 --- a/src/bgp/routing-instance/rtarget_group.sandesh +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. - */ - -struct MemberTableList { - 1: string family; - 2: list tables; -} - -struct ShowRtGroupInfo { - 1: string rtarget (link="ShowRtGroupReq"); - 2: list import_members; - 3: list export_members; - 4: optional list peers_interested; - 5: optional list dep_route; -} - -response sandesh ShowRtGroupResp { - 1: list rtgroup_list; -} - -request sandesh ShowRtGroupReq { - 1: string rtarget; -} - -response sandesh ShowRtGroupPeerResp { - 1: list rtgroup_list; -} - -request sandesh ShowRtGroupPeerReq { - 1: string peer; -} - -response sandesh ShowRtGroupSummaryResp { - 1: list rtgroup_list; -} - -request sandesh ShowRtGroupSummaryReq { -} diff --git a/src/bgp/routing-instance/rtarget_group_mgr.cc b/src/bgp/routing-instance/rtarget_group_mgr.cc index fb21b2b9acf..4bfc5805a38 100644 --- a/src/bgp/routing-instance/rtarget_group_mgr.cc +++ b/src/bgp/routing-instance/rtarget_group_mgr.cc @@ -73,10 +73,6 @@ RTargetGroupMgr::RTargetGroupMgr(BgpServer *server) : server_(server), rtfilter_task_id_ = scheduler->GetTaskId("bgp::RTFilter"); } - process_queue_ = - new WorkQueue(rtfilter_task_id_, 0, - boost::bind(&RTargetGroupMgr::RequestHandler, this, _1)); - for (int i = 0; i < DB::PartitionCount(); i++) { rtarget_dep_triggers_.push_back(boost::shared_ptr(new TaskTrigger(boost::bind(&RTargetGroupMgr::ProcessRouteTargetList, @@ -85,114 +81,6 @@ RTargetGroupMgr::RTargetGroupMgr(BgpServer *server) : server_(server), } } -bool RTargetGroupMgr::RequestHandler(RtGroupMgrReq *req) { - CHECK_CONCURRENCY("bgp::RTFilter"); - - switch (req->type_) { - case RtGroupMgrReq::SHOW_RTGROUP: { - ShowRtGroupResp *snh_resp = - static_cast(req->snh_resp_); - std::vector rtgroup_info_list; - if (req->param_.empty()) { - for (RtGroupMap::const_iterator it = rtgroup_map_.begin(); - it != rtgroup_map_.end(); it++) { - ShowRtGroupInfo info; - const RtGroup *rtgroup = it->second; - rtgroup->FillShowInfo(&info); - rtgroup_info_list.push_back(info); - } - } else { - RouteTarget rtarget = RouteTarget::FromString(req->param_); - RtGroupMap::const_iterator it = rtgroup_map_.find(rtarget); - if (it != rtgroup_map_.end()) { - ShowRtGroupInfo info; - const RtGroup *rtgroup = it->second; - rtgroup->FillShowInfo(&info); - rtgroup_info_list.push_back(info); - } - } - - snh_resp->set_rtgroup_list(rtgroup_info_list); - snh_resp->Response(); - break; - } - case RtGroupMgrReq::SHOW_RTGROUP_PEER: { - ShowRtGroupPeerResp *snh_resp = - static_cast(req->snh_resp_); - std::vector rtgroup_info_list; - for (RtGroupMap::iterator it = rtgroup_map_.begin(); - it != rtgroup_map_.end(); it++) { - ShowRtGroupInfo info; - RtGroup *rtgroup = it->second; - if (!rtgroup->HasInterestedPeer(req->param_)) - continue; - rtgroup->FillShowPeerInfo(&info); - rtgroup_info_list.push_back(info); - } - - snh_resp->set_rtgroup_list(rtgroup_info_list); - snh_resp->Response(); - break; - } - case RtGroupMgrReq::SHOW_RTGROUP_SUMMARY: { - ShowRtGroupSummaryResp *snh_resp = - static_cast(req->snh_resp_); - std::vector rtgroup_info_list; - for (RtGroupMap::iterator it = rtgroup_map_.begin(); - it != rtgroup_map_.end(); it++) { - ShowRtGroupInfo info; - RtGroup *rtgroup = it->second; - rtgroup->FillShowSummaryInfo(&info); - rtgroup_info_list.push_back(info); - } - - snh_resp->set_rtgroup_list(rtgroup_info_list); - snh_resp->Response(); - break; - } - default: { - break; - } - } - - delete req; - return true; -} - -void RTargetGroupMgr::Enqueue(RtGroupMgrReq *req) { - process_queue_->Enqueue(req); -} - -void ShowRtGroupReq::HandleRequest() const { - BgpSandeshContext *bsc = static_cast(client_context()); - RTargetGroupMgr *mgr = bsc->bgp_server->rtarget_group_mgr(); - ShowRtGroupResp *resp = new ShowRtGroupResp; - resp->set_context(context()); - RtGroupMgrReq *req = - new RtGroupMgrReq(RtGroupMgrReq::SHOW_RTGROUP, resp, get_rtarget()); - mgr->Enqueue(req); -} - -void ShowRtGroupPeerReq::HandleRequest() const { - BgpSandeshContext *bsc = static_cast(client_context()); - RTargetGroupMgr *mgr = bsc->bgp_server->rtarget_group_mgr(); - ShowRtGroupPeerResp *resp = new ShowRtGroupPeerResp; - resp->set_context(context()); - RtGroupMgrReq *req = - new RtGroupMgrReq(RtGroupMgrReq::SHOW_RTGROUP_PEER, resp, get_peer()); - mgr->Enqueue(req); -} - -void ShowRtGroupSummaryReq::HandleRequest() const { - BgpSandeshContext *bsc = static_cast(client_context()); - RTargetGroupMgr *mgr = bsc->bgp_server->rtarget_group_mgr(); - ShowRtGroupSummaryResp *resp = new ShowRtGroupSummaryResp; - resp->set_context(context()); - RtGroupMgrReq *req = - new RtGroupMgrReq(RtGroupMgrReq::SHOW_RTGROUP_SUMMARY, resp); - mgr->Enqueue(req); -} - void RTargetGroupMgr::RTargetPeerSync(BgpTable *table, RTargetRoute *rt, DBTableBase::ListenerId id, RTargetState *dbstate, const RtGroup::InterestedPeerList *future) { @@ -464,7 +352,6 @@ bool RTargetGroupMgr::RTargetRouteNotify(DBTablePartBase *root, } RTargetGroupMgr::~RTargetGroupMgr() { - delete process_queue_; assert(rtgroup_map_.empty()); } diff --git a/src/bgp/routing-instance/rtarget_group_mgr.h b/src/bgp/routing-instance/rtarget_group_mgr.h index e048779c213..285f13dd38c 100644 --- a/src/bgp/routing-instance/rtarget_group_mgr.h +++ b/src/bgp/routing-instance/rtarget_group_mgr.h @@ -24,7 +24,6 @@ #include "bgp/bgp_route.h" #include "bgp/community.h" #include "bgp/routing-instance/rtarget_group.h" -#include "bgp/routing-instance/rtarget_group_types.h" #include "bgp/rtarget/rtarget_address.h" #include "db/db_table_partition.h" @@ -203,20 +202,22 @@ struct RtGroupMgrReq { class RTargetGroupMgr { public: typedef boost::ptr_map RtGroupMap; - typedef std::map RtGroupMgrTableStateList; - typedef std::set RTargetRouteTriggerList; - typedef std::set RouteTargetTriggerList; - typedef std::set RtGroupRemoveList; + typedef RtGroupMap::const_iterator const_iterator; explicit RTargetGroupMgr(BgpServer *server); virtual ~RTargetGroupMgr(); + bool empty() const { return rtgroup_map_.empty(); } + const_iterator begin() const { return rtgroup_map_.begin(); } + const_iterator end() const { return rtgroup_map_.end(); } + const_iterator lower_bound(const RouteTarget &rt) const { + return rtgroup_map_.lower_bound(rt); + } + // RtGroup RtGroup *GetRtGroup(const RouteTarget &rt); RtGroup *GetRtGroup(const ExtCommunity::ExtCommunityValue &comm); RtGroup *LocateRtGroup(const RouteTarget &rt); - RtGroupMap &GetRtGroupMap() { return rtgroup_map_; } void NotifyRtGroup(const RouteTarget &rt); void RemoveRtGroup(const RouteTarget &rt); @@ -236,6 +237,12 @@ class RTargetGroupMgr { friend class BgpXmppRTargetTest; friend class ReplicationTest; + typedef std::map RtGroupMgrTableStateList; + typedef std::set RTargetRouteTriggerList; + typedef std::set RouteTargetTriggerList; + typedef std::set RtGroupRemoveList; + void RTargetDepSync(DBTablePartBase *root, BgpRoute *rt, DBTableBase::ListenerId id, VpnRouteState *dbstate, const VpnRouteState::RTargetList *future); @@ -278,7 +285,6 @@ class RTargetGroupMgr { RTargetRouteTriggerList rtarget_route_list_; std::vector rtarget_trigger_lists_; RtGroupRemoveList rtgroup_remove_list_; - WorkQueue *process_queue_; LifetimeRef master_instance_delete_ref_; DISALLOW_COPY_AND_ASSIGN(RTargetGroupMgr); diff --git a/src/bgp/rtarget/rtarget_address.cc b/src/bgp/rtarget/rtarget_address.cc index ea1a2d4c525..06e0ef459ee 100644 --- a/src/bgp/rtarget/rtarget_address.cc +++ b/src/bgp/rtarget/rtarget_address.cc @@ -23,13 +23,14 @@ RouteTarget::RouteTarget(const bytes_type &data) { } const uint64_t RouteTarget::GetExtCommunityValue() const { - return get_value(data_.begin(), 8); + return get_value(data_.begin(), 8); } RouteTarget RouteTarget::FromString(const string &str, boost::system::error_code *errorp) { RouteTarget rt; uint8_t data[RouteTarget::kSize]; + // target:1:2 OR target:1.2.3.4:3 size_t pos = str.find(':'); if (pos == string::npos) { diff --git a/src/bgp/test/SConscript b/src/bgp/test/SConscript index 0387210c098..941d1d7bacd 100644 --- a/src/bgp/test/SConscript +++ b/src/bgp/test/SConscript @@ -250,6 +250,11 @@ bgp_show_routing_instance_test = env.UnitTest('bgp_show_routing_instance_test', env.Alias('src/bgp:bgp_show_routing_instance_test', bgp_show_routing_instance_test) +bgp_show_rtarget_group_test = env.UnitTest('bgp_show_rtarget_group_test', + ['bgp_show_rtarget_group_test.cc']) +env.Alias('src/bgp:bgp_show_rtarget_group_test', + bgp_show_rtarget_group_test) + bgp_stress_test = env.UnitTest('bgp_stress_test', ['bgp_stress_test.cc']) env.Alias('src/bgp:bgp_stress_test', bgp_stress_test) @@ -417,6 +422,7 @@ test_suite = [ bgp_show_neighbor_test, bgp_show_route_summary_test, bgp_show_routing_instance_test, + bgp_show_rtarget_group_test, bgp_stress_test, bgp_table_export_test, bgp_table_test, diff --git a/src/bgp/test/bgp_show_rtarget_group_test.cc b/src/bgp/test/bgp_show_rtarget_group_test.cc new file mode 100644 index 00000000000..ce743ea17d2 --- /dev/null +++ b/src/bgp/test/bgp_show_rtarget_group_test.cc @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +#include "base/test/task_test_util.h" +#include "bgp/bgp_config.h" +#include "bgp/bgp_factory.h" +#include "bgp/bgp_sandesh.h" +#include "bgp/bgp_session_manager.h" +#include "bgp/test/bgp_server_test_util.h" +#include "bgp/test/bgp_test_util.h" +#include "bgp/xmpp_message_builder.h" +#include "control-node/control_node.h" +#include "control-node/test/network_agent_mock.h" +#include "ifmap/ifmap_server_parser.h" +#include "ifmap/test/ifmap_test_util.h" +#include "io/test/event_manager_test.h" +#include "schema/bgp_schema_types.h" +#include "schema/vnc_cfg_types.h" +#include "testing/gunit.h" + +using std::cout; +using std::endl; +using std::string; +using std::vector; + +static const char *config_template = "\ +\ + \ + 192.168.0.1\ + 64512\ +
127.0.0.1
\ + %d\ +
\ +
\ +"; + +class BgpShowRtGroupTest : public ::testing::Test { +public: + void ValidateResponse(Sandesh *sandesh, + vector &result, const string &next_batch) { + const ShowRtGroupResp *resp = + dynamic_cast(sandesh); + TASK_UTIL_EXPECT_TRUE(resp != NULL); + TASK_UTIL_EXPECT_EQ(result.size(), resp->get_rtgroup_list().size()); + TASK_UTIL_EXPECT_EQ(next_batch, resp->get_next_batch()); + for (size_t i = 0; i < resp->get_rtgroup_list().size(); ++i) { + TASK_UTIL_EXPECT_EQ(result[i], + resp->get_rtgroup_list()[i].get_rtarget()); + cout << resp->get_rtgroup_list()[i].log() << endl; + } + validate_done_ = true; + } + +protected: + BgpShowRtGroupTest() + : thread_(&evm_), validate_done_(false) { + } + + virtual void SetUp() { + IFMapServerParser *parser = IFMapServerParser::GetInstance("schema"); + bgp_schema_ParserInit(parser); + vnc_cfg_ParserInit(parser); + + server_.reset(new BgpServerTest(&evm_, "X")); + server_->session_manager()->Initialize(0); + sandesh_context_.bgp_server = server_.get(); + Sandesh::set_client_context(&sandesh_context_); + + thread_.Start(); + Configure(); + task_util::WaitForIdle(); + } + + virtual void TearDown() { + server_->Shutdown(); + task_util::WaitForIdle(); + + IFMapCleanUp(); + task_util::WaitForIdle(); + + evm_.Shutdown(); + thread_.Join(); + task_util::WaitForIdle(); + } + + void IFMapCleanUp() { + IFMapServerParser::GetInstance("vnc_cfg")->MetadataClear("vnc_cfg"); + IFMapServerParser::GetInstance("schema")->MetadataClear("schema"); + } + + void Configure() { + char config[4096]; + snprintf(config, sizeof(config), config_template, + server_->session_manager()->GetPort()); + server_->Configure(config); + task_util::WaitForIdle(); + + TASK_UTIL_EXPECT_EQ(64512, server_->autonomous_system()); + TASK_UTIL_EXPECT_EQ(64512, server_->local_autonomous_system()); + + vector instance_names; + for (int idx = 1; idx <= 12; ++idx) { + string vn_name = string("vn") + integerToString(idx); + instance_names.push_back(vn_name); + } + NetworkConfig(instance_names); + VerifyNetworkConfig(instance_names); + } + + void NetworkConfig(const vector &instance_names) { + string netconf(bgp_util::NetworkConfigGenerate(instance_names)); + IFMapServerParser *parser = IFMapServerParser::GetInstance("schema"); + parser->Receive( + server_->config_db(), netconf.data(), netconf.length(), 0); + task_util::WaitForIdle(); + } + + void VerifyNetworkConfig(const vector &instance_names) { + RoutingInstanceMgr *rim = server_->routing_instance_mgr(); + int idx = 1; + for (vector::const_iterator iter = instance_names.begin(); + iter != instance_names.end(); ++iter, ++idx) { + TASK_UTIL_EXPECT_TRUE(rim->GetRoutingInstance(*iter) != NULL); + const RoutingInstance *rtinstance = rim->GetRoutingInstance(*iter); + TASK_UTIL_EXPECT_EQ(1, rtinstance->GetExportList().size()); + string rtarget_str = string("target:64496:") + integerToString(idx); + TASK_UTIL_EXPECT_EQ(rtarget_str, + rtinstance->GetExportList().begin()->ToString()); + } + } + + string GetRTargetName(int idx) { + string rtarget_name("target:64496:"); + rtarget_name += integerToString(idx); + return rtarget_name; + } + + void AddRTargetName(vector *rtarget_names, int idx) { + rtarget_names->push_back(GetRTargetName(idx)); + } + + EventManager evm_; + ServerThread thread_; + boost::scoped_ptr server_; + bool validate_done_; + BgpSandeshContext sandesh_context_; +}; + +// Parameterize the iteration limit. +class BgpShowRtGroupParamTest : + public BgpShowRtGroupTest, + public ::testing::WithParamInterface { +}; + +// +// Next rtarget = empty +// Page limit = 64 (default) +// Should return all rtargets. +// +TEST_P(BgpShowRtGroupParamTest, Request1) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 12 (number of rtargets) +// Should return all rtargets. +// +TEST_P(BgpShowRtGroupParamTest, Request2) { + sandesh_context_.set_page_limit(12); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 4 +// Should return first 4 rtargets. +// +TEST_P(BgpShowRtGroupParamTest, Request3) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 4; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch = GetRTargetName(5) + "||"; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 64 (default) +// Search string = "" +// Should return all rtargets. +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch1) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string(""); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 64 (default) +// Search string = "64496" +// Should return all rtargets with "64496". +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch2) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string("64496"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 12 (number of matching rtargets) +// Search string = "64496" +// Should return all rtargets with "64496". +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch3) { + sandesh_context_.set_page_limit(12); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string("64496"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 4 +// Search string = "64496" +// Should return first 4 rtargets with "64496". +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch4) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 1; idx <= 4; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch = GetRTargetName(5) + "||64496"; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string("64496"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 64 (default) +// Search string = "xyz" +// Should return empty list. +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch5) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string("xyz"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 64 (default) +// Search string = "target:64496:7" +// Should return 1 rtarget. +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch6) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + AddRTargetName(&rtargets, 7); + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string(GetRTargetName(7)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 1 +// Search string = "target:64496:7" +// Should return 1 rtarget. +// +TEST_P(BgpShowRtGroupParamTest, RequestWithSearch7) { + sandesh_context_.set_page_limit(1); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + AddRTargetName(&rtargets, 7); + string next_batch = GetRTargetName(8) + "||" + GetRTargetName(7); + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReq *req = new ShowRtGroupReq; + req->set_search_string(GetRTargetName(7)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 64 (default) +// Should return all rtargets including and after "target:64496:2" +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate1) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 2; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 11 +// Should return all rtargets including and after "target:64496:2" +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate2) { + sandesh_context_.set_page_limit(11); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 2; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 4 +// Should return first 4 rtargets including and after "target:64496:2" +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate3) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 2; idx <= 5; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch = GetRTargetName(6) + "||"; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = empty +// Page limit = 4 +// Should return empty list. +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate4) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(""); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = malformed +// Page limit = 4 +// Should return empty list. +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate5) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = malformed +// Page limit = 4 +// Should return empty list. +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate6) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "|"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:19" +// Page limit = 4 +// Should return empty list. +// +TEST_P(BgpShowRtGroupParamTest, RequestIterate7) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(19) + "|"); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 64 (default) +// Search string = "target:64496:1" +// Should return 3 matching rtargets including and after "target:64496:10" +// +TEST_P(BgpShowRtGroupParamTest, RequestIterateWithSearch1) { + sandesh_context_.set_page_limit(0); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 10; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||" + GetRTargetName(1)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 3 +// Search string = "target:64496:1" +// Should return 3 matching rtargets including and after "target:64496:10" +// +TEST_P(BgpShowRtGroupParamTest, RequestIterateWithSearch2) { + sandesh_context_.set_page_limit(3); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 10; idx <= 12; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||" + GetRTargetName(1)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 2 +// Search string = "target:64496:1" +// Should return 2 matching rtargets including and after "target:64496:10" +// +TEST_P(BgpShowRtGroupParamTest, RequestIterateWithSearch3) { + sandesh_context_.set_page_limit(2); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + for (int idx = 10; idx <= 11; ++idx) { + AddRTargetName(&rtargets, idx); + } + string next_batch = GetRTargetName(12) + "||" + GetRTargetName(1); + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||" + GetRTargetName(1)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// +// Next rtarget = "target:64496:2" +// Page limit = 4 +// Search string = "target:64496:19" +// Should return empty list. +// +TEST_P(BgpShowRtGroupParamTest, RequestIterateWithSearch4) { + sandesh_context_.set_page_limit(4); + sandesh_context_.set_iter_limit(GetParam()); + vector rtargets; + string next_batch; + Sandesh::set_response_callback(boost::bind( + &BgpShowRtGroupParamTest::ValidateResponse, this, + _1, rtargets, next_batch)); + validate_done_ = false; + ShowRtGroupReqIterate *req = new ShowRtGroupReqIterate; + req->set_iterate_info(GetRTargetName(2) + "||" + GetRTargetName(19)); + req->HandleRequest(); + req->Release(); + TASK_UTIL_EXPECT_TRUE(validate_done_); +} + +// Instantiate for each value of iteration limit from 0 through 9. +// Note that 0 implies the default iteration limit. +INSTANTIATE_TEST_CASE_P(Instance, BgpShowRtGroupParamTest, + ::testing::Range(0, 10)); + +class TestEnvironment : public ::testing::Environment { + virtual ~TestEnvironment() { } +}; + +static void SetUp() { + ControlNode::SetDefaultSchedulingPolicy(); + BgpServerTest::GlobalSetUp(); + BgpObjectFactory::Register( + boost::factory()); +} + +static void TearDown() { + task_util::WaitForIdle(); + 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; +} diff --git a/src/bgp/test/bgp_xmpp_rtarget_test.cc b/src/bgp/test/bgp_xmpp_rtarget_test.cc index dc516d96716..70c318e0481 100644 --- a/src/bgp/test/bgp_xmpp_rtarget_test.cc +++ b/src/bgp/test/bgp_xmpp_rtarget_test.cc @@ -907,8 +907,7 @@ class BgpXmppRTargetTest : public ::testing::Test { TASK_UTIL_EXPECT_EQ(result.size(), resp->get_rtgroup_list().size()); cout << "*****************************************************" << endl; int i = 0; - BOOST_FOREACH(const ShowRtGroupInfo &info, - resp->get_rtgroup_list()) { + BOOST_FOREACH(const ShowRtGroupInfo &info, resp->get_rtgroup_list()) { TASK_UTIL_EXPECT_EQ(info.get_rtarget(), result[i]); cout << info.log() << endl; i++; @@ -927,8 +926,7 @@ class BgpXmppRTargetTest : public ::testing::Test { TASK_UTIL_EXPECT_EQ(result.size(), resp->get_rtgroup_list().size()); cout << "*****************************************************" << endl; int i = 0; - BOOST_FOREACH(const ShowRtGroupInfo &info, - resp->get_rtgroup_list()) { + BOOST_FOREACH(const ShowRtGroupInfo &info, resp->get_rtgroup_list()) { TASK_UTIL_EXPECT_EQ(info.get_rtarget(), result[i]); cout << info.log() << endl; i++; @@ -963,7 +961,7 @@ class BgpXmppRTargetTest : public ::testing::Test { Sandesh::set_response_callback( boost::bind(ValidateRTGroupResponse, _1, result)); ShowRtGroupReq *req = new ShowRtGroupReq; - req->set_rtarget(rtarget); + req->set_search_string(rtarget); validate_done_ = 0; req->HandleRequest(); req->Release(); @@ -980,7 +978,7 @@ class BgpXmppRTargetTest : public ::testing::Test { Sandesh::set_response_callback( boost::bind(ValidateRTGroupPeerResponse, _1, result)); ShowRtGroupPeerReq *req = new ShowRtGroupPeerReq; - req->set_peer(peer); + req->set_search_string(peer); validate_done_ = 0; req->HandleRequest(); req->Release(); @@ -2136,6 +2134,7 @@ TEST_F(BgpXmppRTargetTest, HTTPIntrospect3) { const BgpPeer *peer_cn2 = FindMatchingPeer(mx_.get(), "CN2"); EXPECT_TRUE(peer_cn2 != NULL); VerifyRtGroupPeerSandesh(mx_.get(), peer_cn2->peer_basename(), result); + VerifyRtGroupPeerSandesh(mx_.get(), string(), vector()); VerifyRtGroupPeerSandesh(mx_.get(), "undefined", vector()); VerifyRtGroupPeerSandesh(cn1_.get(), "undefined", vector());