Skip to content

Commit a43dd92

Browse files
Zuul v3 CIopencontrail-ci-admin
authored andcommitted
Merge "Second interface not updated on removing seg health check"
2 parents 3ecf71c + 74e23e2 commit a43dd92

4 files changed

Lines changed: 372 additions & 3 deletions

File tree

src/vnsw/agent/oper/health_check.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ HealthCheckInstanceService::~HealthCheckInstanceService() {
258258
if (service()->IsSegmentHealthCheckService() && other_intf_.get()) {
259259
VmInterface *vmi = static_cast<VmInterface *>(other_intf_.get());
260260
vmi->DeleteHealthCheckInstance(this);
261+
EnqueueResync(service(), other_intf_.get());
261262
}
262263
}
263264

src/vnsw/agent/oper/test/test_health_check.cc

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,27 @@ class HealthCheckConfigTest : public ::testing::Test {
4444
public:
4545
virtual void SetUp() {
4646
agent = Agent::GetInstance();
47+
count_ = 0;
4748
//agent->health_check_table()->set_test_mode(true);
49+
rid_ = Agent::GetInstance()->interface_table()->Register(
50+
boost::bind(&HealthCheckConfigTest::ItfUpdate, this, _2));
51+
TestPkt0Interface *tap = (TestPkt0Interface *)
52+
(Agent::GetInstance()->pkt()->control_interface());
53+
tap->RegisterCallback(
54+
boost::bind(&HealthCheckConfigTest::TestClientReceive, this, _1, _2));
4855
}
4956

5057
virtual void TearDown() {
5158
client->WaitForIdle();
5259
EXPECT_TRUE(agent->health_check_table()->Size() == 0);
60+
Agent::GetInstance()->interface_table()->Unregister(rid_);
5361
}
5462

63+
void TestClientReceive(uint8_t *buf, std::size_t len) {
64+
// Nothing to do for now.
65+
count_++;
66+
return;
67+
}
5568
HealthCheckService *FindHealthCheck(int id) {
5669
HealthCheckTable *table = agent->health_check_table();
5770
boost::uuids::uuid hc_uuid = MakeUuid(id);
@@ -73,8 +86,45 @@ class HealthCheckConfigTest : public ::testing::Test {
7386
client->WaitForIdle();
7487
}
7588

89+
void ItfUpdate(DBEntryBase *entry) {
90+
Interface *itf = static_cast<Interface *>(entry);
91+
tbb::mutex::scoped_lock lock(mutex_);
92+
unsigned int i;
93+
for (i = 0; i < itf_id_.size(); ++i)
94+
if (itf_id_[i] == itf->id())
95+
break;
96+
if (entry->IsDeleted()) {
97+
if (itf_count_ && i < itf_id_.size()) {
98+
itf_count_--;
99+
LOG(DEBUG, "HC test : interface deleted " << itf_id_[0]);
100+
itf_id_.erase(itf_id_.begin()); // we delete in create order
101+
}
102+
} else {
103+
if (i == itf_id_.size()) {
104+
itf_count_++;
105+
itf_id_.push_back(itf->id());
106+
LOG(DEBUG, "HC test : interface added " << itf->id());
107+
}
108+
}
109+
}
110+
111+
uint32_t GetItfCount() {
112+
tbb::mutex::scoped_lock lock(mutex_);
113+
return itf_count_;
114+
}
115+
116+
std::size_t GetItfId(int index) {
117+
tbb::mutex::scoped_lock lock(mutex_);
118+
return itf_id_[index];
119+
}
120+
76121
protected:
77122
Agent *agent;
123+
DBTableBase::ListenerId rid_;
124+
uint32_t itf_count_;
125+
std::vector<std::size_t> itf_id_;
126+
tbb::mutex mutex_;
127+
uint32_t count_;
78128
};
79129

80130
TEST_F(HealthCheckConfigTest, Basic) {
@@ -350,6 +400,218 @@ TEST_F(HealthCheckConfigTest, segment_hc) {
350400
WAIT_FOR(100, 100, (VmInterfaceGet(input[2].intf_id) == NULL));
351401
}
352402

403+
// To test the fix for failure to exchange ICMP messages
404+
// Test segment_hc_1 is updated version of segment_hc above
405+
// The following steps are followed in the test case
406+
// a. Create VM and VMIs.
407+
// b. Attach IPAM to each of VNs created by user.
408+
// c. Create HC service
409+
// d. Create a transparent service template.
410+
// e. Create a service instance with above template
411+
// f. Create port tuple
412+
// g. Associate port tuple with the VMIs.
413+
// h. Associate port tuple with Service Instance.
414+
// i. Associate health check to service instance,
415+
// specifically to the left interface.
416+
// j. clean up in reverse order.
417+
TEST_F(HealthCheckConfigTest, segment_hc_1) {
418+
using boost::uuids::nil_uuid;
419+
420+
struct PortInfo input[] = {
421+
{"vnet10", 10, "1.1.1.10", "00:00:00:01:01:10", 10, 10},
422+
{"vnet11", 11, "2.1.1.10", "00:00:00:01:02:10", 11, 10},
423+
{"vnet12", 12, "3.1.1.10", "00:00:00:01:03:10", 12, 10},
424+
};
425+
426+
CreateVmportEnv(input, 3);
427+
client->WaitForIdle();
428+
429+
IpamInfo ipam_info1[] = {
430+
{"1.1.1.0", 24, "1.1.1.200", true},
431+
};
432+
IpamInfo ipam_info2[] = {
433+
{"2.1.1.0", 24, "2.1.1.200", true},
434+
};
435+
IpamInfo ipam_info3[] = {
436+
{"3.1.1.0", 24, "3.1.1.200", true},
437+
};
438+
AddIPAM("vn10", ipam_info1, 1, NULL, "vdns1");
439+
AddIPAM("vn11", ipam_info2, 1, NULL, "vdns2");
440+
AddIPAM("vn12", ipam_info3, 1, NULL, "vdns3");
441+
client->WaitForIdle();
442+
443+
// Validate health check instance is still NOT running on both left and
444+
VmInterface *intf1 = VmInterfaceGet(input[0].intf_id);
445+
EXPECT_TRUE(intf1 != NULL);
446+
EXPECT_TRUE(intf1->si_other_end_vmi() == nil_uuid());
447+
448+
VmInterface *intf2 = VmInterfaceGet(input[1].intf_id);
449+
EXPECT_TRUE(intf2 != NULL);
450+
EXPECT_TRUE(intf2->si_other_end_vmi() == nil_uuid());
451+
452+
VmInterface *intf3 = VmInterfaceGet(input[2].intf_id);
453+
EXPECT_TRUE(intf3 != NULL);
454+
EXPECT_TRUE(intf3->si_other_end_vmi() == nil_uuid());
455+
456+
EXPECT_TRUE(agent->health_check_table()->Size() == 0);
457+
458+
// Create a Health Check Service
459+
AddHealthCheckService("HC_test", 1, "", "PING", "segment");
460+
client->WaitForIdle();
461+
WAIT_FOR(100, 100, agent->health_check_table()->Size() == 1);
462+
463+
HealthCheckService *hc = FindHealthCheck(1);
464+
EXPECT_TRUE(hc != NULL);
465+
EXPECT_TRUE(hc->name().compare("HC_test") == 0);
466+
EXPECT_TRUE(hc->IsSegmentHealthCheckService() == true);
467+
468+
// Create a Service Template
469+
CreateTransparentV2ST("template-1", true, true, true);
470+
471+
// Create a Service Instance
472+
CreateServiceInstance("instance-1", "vn10", "1.1.1.10",
473+
"vn11", "2.1.1.10", "vn12", "3.1.1.10");
474+
475+
// Link service instance with a service template
476+
AddLink("service-instance", "instance-1",
477+
"service-template", "template-1",
478+
"service-instance-service-template");
479+
480+
// Create a port-tuple
481+
AddNode("port-tuple", "pt1", 1);
482+
client->WaitForIdle();
483+
484+
// Link port-tuple to the VM interfaces
485+
// and to the service instance
486+
AddLink("virtual-machine-interface", "vnet10",
487+
"port-tuple", "pt1", "port-tuple-interface");
488+
client->WaitForIdle();
489+
490+
AddLink("virtual-machine-interface", "vnet11",
491+
"port-tuple", "pt1", "port-tuple-interface");
492+
client->WaitForIdle();
493+
494+
AddLink("virtual-machine-interface", "vnet12",
495+
"port-tuple", "pt1", "port-tuple-interface");
496+
client->WaitForIdle();
497+
498+
AddLink("service-instance", "instance-1",
499+
"port-tuple", "pt1", "service-instance-port-tuple");
500+
client->WaitForIdle();
501+
502+
// Link segment health check to service instance
503+
std::stringstream buf;
504+
buf << "<interface-type>" << "left" << "</interface-type>";
505+
AddLinkNode("service-health-check-service-instance", "HC_test-1", buf.str().c_str());
506+
AddLink("service-health-check-service-instance", "HC_test-1",
507+
"service-instance", "instance-1",
508+
"service-health-check-service-instance");
509+
AddLink("service-health-check-service-instance", "HC_test-1",
510+
"service-health-check", "HC_test",
511+
"service-health-check-service-instance");
512+
client->WaitForIdle();
513+
514+
AddVmiServiceType("vnet10", 10, "management");
515+
AddVmiServiceType("vnet11", 11, "left");
516+
AddVmiServiceType("vnet12", 12, "right");
517+
client->WaitForIdle();
518+
519+
// Associate health-check to left interface
520+
AddLink("virtual-machine-interface", "vnet11",
521+
"service-health-check", "HC_test", "service-port-health-check");
522+
client->WaitForIdle();
523+
524+
//Verify that interface has correct association of other end of SI
525+
WAIT_FOR(100, 1000, (intf1->si_other_end_vmi() == nil_uuid()));
526+
WAIT_FOR(100, 1000, (intf2->si_other_end_vmi() == intf3->GetUuid()));
527+
WAIT_FOR(100, 1000, (intf3->si_other_end_vmi() == intf2->GetUuid()));
528+
529+
// right interfaces because of absence of service_ip on IPAM
530+
WAIT_FOR(100, 1000, intf2->hc_instance_set().size() != 0);
531+
WAIT_FOR(100, 1000, intf3->hc_instance_set().size() != 0);
532+
533+
// Sleep for 6 seconds to allow tx for 3 icmp messages
534+
// of the segment health check to be transmitted.
535+
// Since response to icmp message doesnt come, health
536+
// check fails.
537+
sleep (6);
538+
539+
// Disassociate health-check from left interface
540+
DelLink("virtual-machine-interface", "vnet11",
541+
"service-health-check", "HC_test", "service-port-health-check");
542+
client->WaitForIdle();
543+
544+
DelLink("service-instance", "instance-1",
545+
"port-tuple", "pt1", "service-instance-port-tuple");
546+
client->WaitForIdle();
547+
548+
DelLink("virtual-machine-interface", "vnet10", "port-tuple", "pt1",
549+
"port-tuple-interface");
550+
client->WaitForIdle();
551+
552+
DelLink("virtual-machine-interface", "vnet11", "port-tuple", "pt1",
553+
"port-tuple-interface");
554+
client->WaitForIdle();
555+
556+
DelLink("virtual-machine-interface", "vnet12", "port-tuple", "pt1",
557+
"port-tuple-interface");
558+
client->WaitForIdle();
559+
560+
DelNode("port-tuple", "pt1");
561+
client->WaitForIdle();
562+
563+
DelLink("service-health-check-service-instance", "HC_test-1",
564+
"service-health-check", "HC_test",
565+
"service-health-check-service-instance");
566+
DelLink("service-health-check-service-instance", "HC_test-1",
567+
"service-instance", "instance-1",
568+
"service-health-check-service-instance");
569+
DelNode("service-health-check-service-instance", "HC_test-1");
570+
client->WaitForIdle();
571+
572+
DelLink("service-instance", "instance-1",
573+
"service-template", "template-1",
574+
"service-instance-service-template");
575+
576+
DeleteServiceInstance("instance-1");
577+
client->WaitForIdle();
578+
579+
DeleteServiceTemplate("template-1");
580+
client->WaitForIdle();
581+
582+
// Validate health check instance is NOT running on both left and right
583+
// interface
584+
WAIT_FOR(100, 100, intf2->hc_instance_set().size() == 0);
585+
WAIT_FOR(100, 100, intf3->hc_instance_set().size() == 0);
586+
587+
WAIT_FOR(100, 100, (intf1->si_other_end_vmi() == nil_uuid()));
588+
WAIT_FOR(100, 100, (intf2->si_other_end_vmi() == nil_uuid()));
589+
WAIT_FOR(100, 100, (intf3->si_other_end_vmi() == nil_uuid()));
590+
591+
DelHealthCheckService("HC_test");
592+
client->WaitForIdle();
593+
WAIT_FOR(100, 100, (FindHealthCheck(1) == NULL));
594+
595+
EXPECT_TRUE((count_ >= 1));
596+
597+
EXPECT_TRUE(intf1->ipv4_active());
598+
EXPECT_TRUE(intf2->ipv4_active());
599+
EXPECT_TRUE(intf3->ipv4_active());
600+
601+
DelIPAM("vn10", "vdns1");
602+
DelIPAM("vn11", "vdns2");
603+
DelIPAM("vn12", "vdns3");
604+
client->WaitForIdle();
605+
606+
DeleteVmportEnv(input, 3, true);
607+
client->WaitForIdle();
608+
609+
WAIT_FOR(100, 100, (VmInterfaceGet(input[0].intf_id) == NULL));
610+
WAIT_FOR(100, 100, (VmInterfaceGet(input[1].intf_id) == NULL));
611+
WAIT_FOR(100, 100, (VmInterfaceGet(input[2].intf_id) == NULL));
612+
client->WaitForIdle();
613+
}
614+
353615
int main(int argc, char **argv) {
354616
GETUSERARGS();
355617

src/vnsw/agent/test/test_cmn_util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,5 +815,13 @@ void DelLrRoutingVrf(int lr_id);
815815
void AddLrBridgeVrf(const std::string &vmi_name, int lr_id,
816816
const char *lr_type = NULL);
817817
void DelLrBridgeVrf(const std::string &vmi_name, int lr_id);
818+
void CreateTransparentV2ST(const char *service_template, bool mgmt,
819+
bool left, bool right);
820+
void DeleteServiceTemplate(const char *service_template);
821+
void CreateServiceInstance(const char *service_instance,
822+
const char *mgmt, const char *mgmt_ip,
823+
const char *left, const char *left_ip,
824+
const char *right, const char *right_ip);
825+
void DeleteServiceInstance(const char *service_instance);
818826

819827
#endif // vnsw_agent_test_cmn_util_h

0 commit comments

Comments
 (0)