Skip to content

Commit

Permalink
Merge "PathPreference state not cleaned."
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Jul 14, 2015
2 parents ca6ddbe + 8aeedf8 commit e6e07d4
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/vnsw/agent/oper/path_preference.cc
Expand Up @@ -658,7 +658,7 @@ void PathPreferenceRouteListener::Init() {
}

void PathPreferenceRouteListener::Delete() {
deleted_ = true;
set_deleted();
DBTableWalker *walker = agent_->db()->GetWalker();
walker->WalkTable(rt_table_, NULL,
boost::bind(&PathPreferenceRouteListener::DeleteState,
Expand Down Expand Up @@ -702,6 +702,8 @@ void PathPreferenceRouteListener::Notify(DBTablePartBase *partition,
return;
}

if (deleted_) return;

AgentRoute *rt = static_cast<AgentRoute *>(e);
for (Route::PathList::iterator it = rt->GetPathList().begin();
it != rt->GetPathList().end(); ++it) {
Expand Down
5 changes: 4 additions & 1 deletion src/vnsw/agent/oper/path_preference.h
Expand Up @@ -156,13 +156,16 @@ struct PathPreferenceVrfState: public DBState {

struct PathPreferenceRouteListener : public DBState {
PathPreferenceRouteListener(Agent *agent, AgentRouteTable *table);
virtual void Delete();

void Notify(DBTablePartBase *partition, DBEntryBase *e);
void Init();
void Delete();
bool DeleteState(DBTablePartBase *partition, DBEntryBase *e);
void Walkdone(DBTableBase *partition, PathPreferenceRouteListener *state);
DBTableBase::ListenerId id() const { return id_;}
void ManagedDelete();
void set_deleted() {deleted_ = true;}
bool deleted() const {return deleted_;}
private:
Agent *agent_;
AgentRouteTable *rt_table_;
Expand Down
3 changes: 3 additions & 0 deletions src/vnsw/agent/test/SConscript
Expand Up @@ -63,6 +63,9 @@ test_fip_cfg = AgentEnv.MakeTestCmd(env, 'test_fip_cfg', flaky_agent_suite)
test_route = AgentEnv.MakeTestCmd(env, 'test_route', flaky_agent_suite)
test_l2route = AgentEnv.MakeTestCmd(env, 'test_l2route', flaky_agent_suite)
test_cfg = AgentEnv.MakeTestCmd(env, 'test_cfg', flaky_agent_suite)
test_path_preference_walker = AgentEnv.MakeTestCmd(env,
'test_path_preference_walker',
agent_suite)
test_xmpp_hv2 = AgentEnv.MakeTestCmd(env, 'test_xmpp_hv2', flaky_agent_suite)
test_xmpp_non_hv = AgentEnv.MakeTestCmd(env, 'test_xmpp_non_hv', flaky_agent_suite)
test_xmppcs_hv = AgentEnv.MakeTestCmd(env, 'test_xmppcs_hv', flaky_agent_suite)
Expand Down
210 changes: 210 additions & 0 deletions src/vnsw/agent/test/test_path_preference_walker.cc
@@ -0,0 +1,210 @@
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/

#include "base/os.h"
#include <base/logging.h>
#include <io/event_manager.h>
#include <boost/shared_ptr.hpp>

#include "cfg/cfg_init.h"
#include "cfg/cfg_interface.h"
#include "oper/operdb_init.h"
#include "oper/agent_path.h"
#include "oper/path_preference.h"
#include "controller/controller_init.h"
#include "pkt/pkt_init.h"
#include "services/services_init.h"
#include "test_cmn_util.h"

using namespace std;

void RouterIdDepInit(Agent *agent) {
}

static void ValidateSandeshResponse(Sandesh *sandesh, vector<int> &result) {
//TBD
//Validate the response by the expectation
}

struct PortInfo input_1[] = {
{"vnet1", 1, "1.1.1.10", "00:00:01:01:01:10", 1, 1},
};

struct PortInfo input_2[] = {
{"vnet2", 2, "2.2.2.20", "00:00:02:02:02:20", 2, 2},
};

struct PortInfo input_3[] = {
{"vnet3", 3, "3.3.3.30", "00:00:03:03:03:30", 3, 3},
};

struct TestPathPreferenceRouteListener : public PathPreferenceRouteListener {
TestPathPreferenceRouteListener(Agent *agent, AgentRouteTable *table) :
PathPreferenceRouteListener(agent, table), walk_done_(false) { }
bool DeleteState(DBTablePartBase *partition, DBEntryBase *e) {
bool ret = PathPreferenceRouteListener::DeleteState(partition, e);
PathPreferenceRouteListener::Notify(partition, e);
return ret;
}
void Walkdone(DBTableBase *partition, PathPreferenceRouteListener *state) {
PathPreferenceRouteListener::Walkdone(partition, state);
walk_done_ = true;
}
virtual void Delete() { } //Dont call parent delete as it will start
// parallel walk

bool walk_done_;
};

class PathPreferenceRouteTableWalkerTest : public ::testing::Test {
public:
PathPreferenceRouteTableWalkerTest() {
vrf_name_1_ = "vrf1";
vrf_name_2_ = "vrf2";
vrf_name_3_ = "vrf3";
server_ip_ = Ip4Address::from_string("10.1.1.11");
local_vm_ip_1_ = Ip4Address::from_string("1.1.1.10");
local_vm_ip_2_ = Ip4Address::from_string("2.2.2.20");
remote_vm_ip_ = Ip4Address::from_string("1.1.1.11");
test_listener_ = NULL;
agent_ = Agent::GetInstance();
};
~PathPreferenceRouteTableWalkerTest() {
}

void SetupEnvironment(int num_vrfs) {
client->Reset();
if (num_vrfs == 0)
return;

if (num_vrfs > 0) {
VrfAddReq(vrf_name_1_.c_str());
}
if (num_vrfs > 1) {
VrfAddReq(vrf_name_2_.c_str());
}
if (num_vrfs > 2) {
VrfAddReq(vrf_name_3_.c_str());
}
VrfEntry *vrf = VrfGet("vrf1", false);
WAIT_FOR(1000, 1000, vrf->GetEvpnRouteTable() != NULL);
EvpnAgentRouteTable *evpn_rt_table =
static_cast<EvpnAgentRouteTable*>(vrf->GetEvpnRouteTable());
test_listener_ =
new TestPathPreferenceRouteListener(agent_, evpn_rt_table);
client->WaitForIdle();
test_listener_->Init();
client->WaitForIdle();
InetInterfaceKey vhost_intf_key(
Agent::GetInstance()->vhost_interface()->name());
Agent::GetInstance()->fabric_inet4_unicast_table()->AddResolveRoute(
Agent::GetInstance()->local_peer(),
Agent::GetInstance()->fabric_vrf_name(), server_ip_, 24,
vhost_intf_key, 0, false, "", SecurityGroupList());
client->WaitForIdle();
client->WaitForIdle();
if (num_vrfs > 0) {
CreateVmportEnv(input_1, 1);
}
if (num_vrfs > 1) {
CreateVmportEnv(input_2, 1);
}
if (num_vrfs > 2) {
CreateVmportEnv(input_3, 1);
}
client->WaitForIdle();
client->Reset();
}

void DeleteEnvironment(int num_vrfs) {
client->Reset();

if (num_vrfs == 0)
return;

if (num_vrfs > 0) {
DeleteVmportEnv(input_1, 1, true);
}
if (num_vrfs > 1) {
DeleteVmportEnv(input_2, 1, true);
}
if (num_vrfs > 2) {
DeleteVmportEnv(input_3, 1, true);
}
client->WaitForIdle();
if (num_vrfs > 0) {
VrfDelReq(vrf_name_1_.c_str());
client->WaitForIdle();
WAIT_FOR(100, 100, (VrfFind(vrf_name_1_.c_str()) != true));
}
if (num_vrfs > 1) {
VrfDelReq(vrf_name_2_.c_str());
client->WaitForIdle();
WAIT_FOR(100, 100, (VrfFind(vrf_name_2_.c_str()) != true));
}
if (num_vrfs > 2) {
VrfDelReq(vrf_name_3_.c_str());
client->WaitForIdle();
WAIT_FOR(100, 100, (VrfFind(vrf_name_3_.c_str()) != true));
}
client->WaitForIdle();
}

virtual void SetUp() {
client->Reset();
VxLanNetworkIdentifierMode(false);
client->WaitForIdle();
AddEncapList("MPLSoGRE", "MPLSoUDP", "VXLAN");
client->WaitForIdle();
}

virtual void TearDown() {
client->Reset();
DelEncapList();
client->WaitForIdle();
}

std::string vrf_name_1_;
std::string vrf_name_2_;
std::string vrf_name_3_;
Ip4Address local_vm_ip_1_;
Ip4Address local_vm_ip_2_;
Ip4Address remote_vm_ip_;
Ip4Address server_ip_;
TestPathPreferenceRouteListener *test_listener_;
Agent *agent_;
};

TEST_F(PathPreferenceRouteTableWalkerTest, notify_on_deleted_before_walk_done) {
client->Reset();
SetupEnvironment(3);
VrfDelReq("vrf1");
client->WaitForIdle();
DBTableWalker *walker = agent_->db()->GetWalker();
VrfEntry *vrf = VrfGet("vrf1", true);
EvpnAgentRouteTable *evpn_rt_table =
static_cast<EvpnAgentRouteTable*>(vrf->GetEvpnRouteTable());
test_listener_->set_deleted();//Artificially mark it for delete
walker->WalkTable(evpn_rt_table, NULL,
boost::bind(&TestPathPreferenceRouteListener::DeleteState,
test_listener_, _1, _2),
boost::bind(&TestPathPreferenceRouteListener::Walkdone,
test_listener_, _1, test_listener_));
WAIT_FOR(1000, 1000, (test_listener_->walk_done_ == true));
DeleteEnvironment(3);
}

//TODO REMAINING TESTS
// - based on walktype - unicast/multicast/all
//
int main(int argc, char **argv) {
GETUSERARGS();

client = TestInit(init_file, ksync_init);
int ret = RUN_ALL_TESTS();
client->WaitForIdle();
TestShutdown();
delete client;
return ret;
}

0 comments on commit e6e07d4

Please sign in to comment.