X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_flowprobe.py;h=a7a09fca19bd4baa405a65757fdd6bcff1a675f9;hb=bd46907b3f27b480e5f8b0be9cb4c5b5f1fa08ab;hp=625bb3a2a29f1d7dea006527316d02aafc5bec51;hpb=a5b2eec0535f9025319a752891d77ff9948ae0df;p=vpp.git diff --git a/test/test_flowprobe.py b/test/test_flowprobe.py index 625bb3a2a29..a7a09fca19b 100644 --- a/test/test_flowprobe.py +++ b/test/test_flowprobe.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from __future__ import print_function import binascii import random @@ -12,12 +12,17 @@ from scapy.layers.l2 import Ether from scapy.layers.inet import IP, TCP, UDP from scapy.layers.inet6 import IPv6 +from framework import tag_fixme_vpp_workers from framework import VppTestCase, VppTestRunner, running_extended_tests +from framework import tag_run_solo from vpp_object import VppObject from vpp_pg_interface import CaptureTimeoutError from util import ppp from ipfix import IPFIX, Set, Template, Data, IPFIXDecoder from vpp_ip_route import VppIpRoute, VppRoutePath +from vpp_papi.macaddress import mac_ntop +from socket import inet_ntop +from vpp_papi import VppEnum class VppCFLOW(VppObject): @@ -40,9 +45,21 @@ class VppCFLOW(VppObject): def add_vpp_config(self): self.enable_exporter() - self._test.vapi.ppcli("flowprobe params record %s active %s " - "passive %s" % (self._collect, self._active, - self._passive)) + l2_flag = 0 + l3_flag = 0 + l4_flag = 0 + if 'l2' in self._collect.lower(): + l2_flag = (VppEnum.vl_api_flowprobe_record_flags_t. + FLOWPROBE_RECORD_FLAG_L2) + if 'l3' in self._collect.lower(): + l3_flag = (VppEnum.vl_api_flowprobe_record_flags_t. + FLOWPROBE_RECORD_FLAG_L3) + if 'l4' in self._collect.lower(): + l4_flag = (VppEnum.vl_api_flowprobe_record_flags_t. + FLOWPROBE_RECORD_FLAG_L4) + self._test.vapi.flowprobe_params( + record_flags=(l2_flag | l3_flag | l4_flag), + active_timer=self._active, passive_timer=self._passive) self.enable_flowprobe_feature() self._test.vapi.cli("ipfix flush") self._configured = True @@ -55,8 +72,8 @@ class VppCFLOW(VppObject): def enable_exporter(self): self._test.vapi.set_ipfix_exporter( - collector_address=self._test.pg0.remote_ip4n, - src_address=self._test.pg0.local_ip4n, + collector_address=self._test.pg0.remote_ip4, + src_address=self._test.pg0.local_ip4, path_mtu=self._mtu, template_interval=self._timeout) @@ -72,26 +89,17 @@ class VppCFLOW(VppObject): (self._intf, self._datapath)) def object_id(self): - return "ipfix-collector-%s" % (self._src, self.dst) + return "ipfix-collector-%s-%s" % (self._src, self.dst) def query_vpp_config(self): return self._configured def verify_templates(self, decoder=None, timeout=1, count=3): templates = [] - p = self._test.wait_for_cflow_packet(self._test.collector, 2, timeout) - self._test.assertTrue(p.haslayer(IPFIX)) - if decoder is not None and p.haslayer(Template): - templates.append(p[Template].templateID) - decoder.add_template(p.getlayer(Template)) - if count > 1: - p = self._test.wait_for_cflow_packet(self._test.collector, 2) - self._test.assertTrue(p.haslayer(IPFIX)) - if decoder is not None and p.haslayer(Template): - templates.append(p[Template].templateID) - decoder.add_template(p.getlayer(Template)) - if count > 2: - p = self._test.wait_for_cflow_packet(self._test.collector, 2) + self._test.assertIn(count, (1, 2, 3)) + for _ in range(count): + p = self._test.wait_for_cflow_packet(self._test.collector, 2, + timeout) self._test.assertTrue(p.haslayer(IPFIX)) if decoder is not None and p.haslayer(Template): templates.append(p[Template].templateID) @@ -232,7 +240,7 @@ class MethodHolder(VppTestCase): ip_layer = capture[0][IPv6] if data_set is not None: for record in data: - # skip flow if in/out gress interface is 0 + # skip flow if ingress/egress interface is 0 if int(binascii.hexlify(record[10]), 16) == 0: continue if int(binascii.hexlify(record[14]), 16) == 0: @@ -270,7 +278,7 @@ class MethodHolder(VppTestCase): value = int(capture[0][UDP].dport) self.assertEqual(int(binascii.hexlify( record[field]), 16), - value) + value) def verify_cflow_data_notimer(self, decoder, capture, cflows): idx = 0 @@ -289,45 +297,23 @@ class MethodHolder(VppTestCase): binascii.hexlify(rec[2]), 16)) self.assertEqual(len(capture), idx) - def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1, - expected=True): + def wait_for_cflow_packet(self, collector_intf, set_id=2, timeout=1): """ wait for CFLOW packet and verify its correctness :param timeout: how long to wait - :returns: tuple (packet, time spent waiting for packet) """ self.logger.info("IPFIX: Waiting for CFLOW packet") - deadline = time.time() + timeout - counter = 0 # self.logger.debug(self.vapi.ppcli("show flow table")) - while True: - counter += 1 - # sanity check - self.assert_in_range(counter, 0, 100, "number of packets ignored") - time_left = deadline - time.time() - try: - if time_left < 0 and expected: - # self.logger.debug(self.vapi.ppcli("show flow table")) - raise CaptureTimeoutError( - "Packet did not arrive within timeout") - p = collector_intf.wait_for_packet(timeout=time_left) - except CaptureTimeoutError: - if expected: - # self.logger.debug(self.vapi.ppcli("show flow table")) - raise CaptureTimeoutError( - "Packet did not arrive within timeout") - else: - return - if not expected: - raise CaptureTimeoutError("Packet arrived even not expected") - self.assertEqual(p[Set].setID, set_id) - # self.logger.debug(self.vapi.ppcli("show flow table")) - self.logger.debug(ppp("IPFIX: Got packet:", p)) - break + p = collector_intf.wait_for_packet(timeout=timeout) + self.assertEqual(p[Set].setID, set_id) + # self.logger.debug(self.vapi.ppcli("show flow table")) + self.logger.debug(ppp("IPFIX: Got packet:", p)) return p +@tag_run_solo +@tag_fixme_vpp_workers class Flowprobe(MethodHolder): """Template verification, timer tests""" @@ -413,7 +399,7 @@ class Flowprobe(MethodHolder): src=self.pg7.remote_mac) / IP(src=self.pg7.remote_ip4, dst="9.0.0.100") / TCP(sport=1234, dport=4321, flags=80) / - Raw('\xa5' * 100))] + Raw(b'\xa5' * 100))] nowUTC = int(time.time()) nowUNIX = nowUTC+2208988800 @@ -436,11 +422,9 @@ class Flowprobe(MethodHolder): # packets self.assertEqual(int(binascii.hexlify(record[2]), 16), 1) # src mac - self.assertEqual(':'.join(re.findall('..', record[56].encode( - 'hex'))), self.pg8.local_mac) + self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac) # dst mac - self.assertEqual(':'.join(re.findall('..', record[80].encode( - 'hex'))), self.pg8.remote_mac) + self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac) flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32 # flow start timestamp self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1) @@ -450,15 +434,11 @@ class Flowprobe(MethodHolder): # ethernet type self.assertEqual(int(binascii.hexlify(record[256]), 16), 8) # src ip - self.assertEqual('.'.join(re.findall('..', record[8].encode( - 'hex'))), - '.'.join('{:02x}'.format(int(n)) for n in - self.pg7.remote_ip4.split('.'))) + self.assertEqual(inet_ntop(socket.AF_INET, record[8]), + self.pg7.remote_ip4) # dst ip - self.assertEqual('.'.join(re.findall('..', record[12].encode( - 'hex'))), - '.'.join('{:02x}'.format(int(n)) for n in - "9.0.0.100".split('.'))) + self.assertEqual(inet_ntop(socket.AF_INET, record[12]), + "9.0.0.100") # protocol (TCP) self.assertEqual(int(binascii.hexlify(record[4]), 16), 6) # src port @@ -472,6 +452,7 @@ class Flowprobe(MethodHolder): self.logger.info("FFP_TEST_FINISH_0000") +@tag_fixme_vpp_workers class Datapath(MethodHolder): """collect information on Ethernet, IP4 and IP6 datapath (no timers)""" @@ -492,7 +473,7 @@ class Datapath(MethodHolder): ipfix.add_vpp_config() # template packet should arrive immediately - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() ipfix.verify_templates(timeout=3, count=1) self.collector.get_capture(1) @@ -516,7 +497,7 @@ class Datapath(MethodHolder): capture = self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 256: 8}) @@ -542,7 +523,7 @@ class Datapath(MethodHolder): capture = self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 4: 17, @@ -570,7 +551,7 @@ class Datapath(MethodHolder): capture = self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 7: 'sport', 11: 'dport'}) @@ -590,7 +571,7 @@ class Datapath(MethodHolder): ipfix.add_vpp_config() # template packet should arrive immediately - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() ipfix.verify_templates(timeout=3, count=1) self.collector.get_capture(1) @@ -615,7 +596,7 @@ class Datapath(MethodHolder): capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4) # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 256: 8}) @@ -643,7 +624,7 @@ class Datapath(MethodHolder): capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4) # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {1: 'octets', 2: 'packets', @@ -672,7 +653,7 @@ class Datapath(MethodHolder): capture = self.send_packets(src_if=self.pg3, dst_if=self.pg4) # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 7: 'sport', 11: 'dport'}) @@ -717,7 +698,7 @@ class Datapath(MethodHolder): capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6) # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 256: 56710}, @@ -747,7 +728,7 @@ class Datapath(MethodHolder): capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6) # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', @@ -778,7 +759,7 @@ class Datapath(MethodHolder): capture = self.send_packets(src_if=self.pg5, dst_if=self.pg6) # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[0]) self.verify_cflow_data_detail(ipfix_decoder, capture, cflow, {2: 'packets', 7: 'sport', 11: 'dport'}, @@ -807,7 +788,7 @@ class Datapath(MethodHolder): capture = self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflow = self.wait_for_cflow_packet(self.collector, templates[1]) self.verify_cflow_data_notimer(ipfix_decoder, capture, [cflow]) self.collector.get_capture(4) @@ -826,7 +807,7 @@ class Datapath(MethodHolder): ipfix_decoder = IPFIXDecoder() # template packet should arrive immediately - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() templates = ipfix.verify_templates(ipfix_decoder) self.create_stream(packets=6) @@ -834,7 +815,7 @@ class Datapath(MethodHolder): # make sure the one packet we expect actually showed up cflows = [] - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() cflows.append(self.wait_for_cflow_packet(self.collector, templates[1])) cflows.append(self.wait_for_cflow_packet(self.collector, @@ -875,21 +856,20 @@ class DisableIPFIX(MethodHolder): self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() self.wait_for_cflow_packet(self.collector, templates[1]) self.collector.get_capture(4) - # disble IPFIX + # disable IPFIX ipfix.disable_exporter() self.pg_enable_capture([self.collector]) self.send_packets() # make sure no one packet arrived in 1 minute - self.vapi.cli("ipfix flush") - self.wait_for_cflow_packet(self.collector, templates[1], - expected=False) - self.collector.get_capture(0) + self.vapi.ipfix_flush() + self.sleep(1, "wait before verifying no packets sent") + self.collector.assert_nothing_captured() ipfix.remove_vpp_config() self.logger.info("FFP_TEST_FINISH_0001") @@ -925,22 +905,21 @@ class ReenableIPFIX(MethodHolder): self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() self.wait_for_cflow_packet(self.collector, templates[1]) self.collector.get_capture(4) # disable IPFIX ipfix.disable_exporter() - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() self.pg_enable_capture([self.collector]) self.send_packets() # make sure no one packet arrived in active timer span - self.vapi.cli("ipfix flush") - self.wait_for_cflow_packet(self.collector, templates[1], - expected=False) - self.collector.get_capture(0) + self.vapi.ipfix_flush() + self.sleep(1, "wait before verifying no packets sent") + self.collector.assert_nothing_captured() self.pg2.get_capture(5) # enable IPFIX @@ -992,21 +971,20 @@ class DisableFP(MethodHolder): self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() self.wait_for_cflow_packet(self.collector, templates[1]) self.collector.get_capture(4) - # disble IPFIX + # disable IPFIX ipfix.disable_flowprobe_feature() self.pg_enable_capture([self.collector]) self.send_packets() # make sure no one packet arrived in active timer span - self.vapi.cli("ipfix flush") - self.wait_for_cflow_packet(self.collector, templates[1], - expected=False) - self.collector.get_capture(0) + self.vapi.ipfix_flush() + self.sleep(1, "wait before verifying no packets sent") + self.collector.assert_nothing_captured() ipfix.remove_vpp_config() self.logger.info("FFP_TEST_FINISH_0001") @@ -1036,39 +1014,38 @@ class ReenableFP(MethodHolder): ipfix_decoder = IPFIXDecoder() # template packet should arrive immediately - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() templates = ipfix.verify_templates(ipfix_decoder, timeout=3) self.create_stream() self.send_packets() # make sure the one packet we expect actually showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() self.wait_for_cflow_packet(self.collector, templates[1], 5) self.collector.get_capture(4) - # disble FPP feature + # disable FPP feature ipfix.disable_flowprobe_feature() self.pg_enable_capture([self.collector]) self.send_packets() # make sure no one packet arrived in active timer span - self.vapi.cli("ipfix flush") - self.wait_for_cflow_packet(self.collector, templates[1], 5, - expected=False) - self.collector.get_capture(0) + self.vapi.ipfix_flush() + self.sleep(5, "wait before verifying no packets sent") + self.collector.assert_nothing_captured() # enable FPP feature ipfix.enable_flowprobe_feature() - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() templates = ipfix.verify_templates(ipfix_decoder, timeout=3) self.send_packets() # make sure the next packets (templates and data) we expect actually # showed up - self.vapi.cli("ipfix flush") + self.vapi.ipfix_flush() self.wait_for_cflow_packet(self.collector, templates[1], 5) self.collector.get_capture(4)