Skip to content

[pfcwd]: Iterate functional test over all ports #490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 70 additions & 24 deletions ansible/roles/test/files/ptftests/pfc_wd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import random
import socket
import sys
import struct
import ipaddress
import re

import ptf
import ptf.packet as scapy
Expand All @@ -13,6 +16,7 @@
from ptf.mask import Mask
from ptf.testutils import *


class PfcWdTest(BaseTest):
def __init__(self):
BaseTest.__init__(self)
Expand All @@ -24,41 +28,83 @@ def setUp(self):
self.queue_index = int(self.test_params['queue_index'])
self.pkt_count = int(self.test_params['pkt_count'])
self.port_src = int(self.test_params['port_src'])
self.ip_src = self.test_params['ip_src']
self.port_dst = self.test_params['port_dst']
self.ip_dst = self.test_params['ip_dst']
self.port_type = self.test_params['port_type']
self.wd_action = self.test_params.get('wd_action', 'drop')

def runTest(self):
ecn = 1
dscp = self.queue_index
tos = dscp << 2
tos |= ecn
dst_port_list = range(0,32)
sport = random.randint(0, 65535)
dport = random.randint(0, 65535)

matches = re.findall('\[([\d\s]+)\]', self.port_dst)

dst_port_list = []
for match in matches:
for port in match.split():
dst_port_list.append(int(port))
src_mac = self.dataplane.get_mac(0, 0)

pkt = simple_tcp_packet(
eth_dst=self.router_mac,
eth_src=src_mac,
ip_src=self.ip_src,
ip_dst=self.ip_dst,
ip_tos = tos,
tcp_sport=sport,
tcp_dport=dport,
ip_ttl=64)
exp_pkt = simple_tcp_packet(
eth_src=self.router_mac,
ip_src=self.ip_src,
ip_dst=self.ip_dst,
ip_tos = tos,
tcp_sport=sport,
tcp_dport=dport,
ip_ttl=63)
masked_exp_pkt = Mask(exp_pkt)
masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
if self.port_type == "portchannel":
for x in range(0, self.pkt_count):
sport = random.randint(0, 65535)
dport = random.randint(0, 65535)
ip_src = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
ip_src =ipaddress.IPv4Address(unicode(ip_src,'utf-8'))
while ip_src == ipaddress.IPv4Address(unicode(self.ip_dst,'utf-8')) or ip_src.is_multicast or ip_src.is_private or ip_src.is_global or ip_src.is_reserved:
ip_src = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
ip_src =ipaddress.IPv4Address(unicode(ip_src,'utf-8'))

ip_src = str(ip_src)
pkt = simple_tcp_packet(
eth_dst=self.router_mac,
eth_src=src_mac,
ip_src=ip_src,
ip_dst=self.ip_dst,
ip_tos = tos,
tcp_sport=sport,
tcp_dport=dport,
ip_ttl=64)
exp_pkt = simple_tcp_packet(
eth_src=self.router_mac,
ip_src=ip_src,
ip_dst=self.ip_dst,
ip_tos = tos,
tcp_sport=sport,
tcp_dport=dport,
ip_ttl=63)
masked_exp_pkt = Mask(exp_pkt)
masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

send_packet(self, self.port_src, pkt, 1)
else:
sport = random.randint(0, 65535)
dport = random.randint(0, 65535)
ip_src = "1.1.1.1"

pkt = simple_tcp_packet(
eth_dst=self.router_mac,
eth_src=src_mac,
ip_src=ip_src,
ip_dst=self.ip_dst,
ip_tos = tos,
tcp_sport=sport,
tcp_dport=dport,
ip_ttl=64)
exp_pkt = simple_tcp_packet(
eth_src=self.router_mac,
ip_src=ip_src,
ip_dst=self.ip_dst,
ip_tos = tos,
tcp_sport=sport,
tcp_dport=dport,
ip_ttl=63)
masked_exp_pkt = Mask(exp_pkt)
masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

send_packet(self, self.port_src, pkt, self.pkt_count)
send_packet(self, self.port_src, pkt, self.pkt_count)

if self.wd_action == 'drop':
return verify_no_packet_any(self, masked_exp_pkt, dst_port_list)
Expand Down
3 changes: 3 additions & 0 deletions ansible/roles/test/tasks/interface.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
- name: Gather minigraph facts about the device
minigraph_facts: host={{inventory_hostname}}

- name: Get interface facts
interface_facts: up_ports={{minigraph_ports}}

Expand Down
74 changes: 68 additions & 6 deletions ansible/roles/test/tasks/pfc_wd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,86 @@
- set_fact:
neighbors: "{{device_conn}}"

- set_fact:
ansible_eth0_ipv4_addr: "{{ansible_eth0['ipv4']['address']}}"
ansible_ethernet0_mac_addr: "{{ansible_Ethernet0['macaddress']}}"

- set_fact:
used: false
first_pair: false
pfc_wd_rx_port: "rx"
pfc_wd_test_port: "test"

- set_fact:
test_ports: {}

- name: Iterate all interfaces to get all interface ports info if exists
include: roles/test/tasks/pfc_wd/iterate_interfaces.yml
with_items: "{{minigraph_interfaces}}"
when: item['addr'] | ipv4

- set_fact:
restart: True
when: minigraph_portchannels| length > 0

- name: Iterate all the portchannels to get all portchanel member ports info if exists.
include: roles/test/tasks/pfc_wd/iterate_portchannels.yml
with_dict: "{{minigraph_portchannels}}"

- name: Generate ips in VLAN range
get_ip_in_range: num=1 prefix="{{minigraph_vlan_interfaces[0]['addr']}}/{{minigraph_vlan_interfaces[0]['prefixlen']}}" exclude_ips="{{minigraph_vlan_interfaces[0]['addr']}}"
become: no
connection: local
failed_when: False
when: minigraph_vlans | length >0

- name: Set unique MACs to PTF interfaces
script: roles/test/files/helpers/change_mac.sh
delegate_to: "{{ptf_host}}"
when: minigraph_vlans | length >0

- set_fact:
vlan_members: "{{minigraph_vlans[minigraph_vlans.keys()[0]]['members']}}"
when: minigraph_vlans | length >0

- name: Iterate all vlan members to get all vlan member ports info if exists.
include: roles/test/tasks/pfc_wd/iterate_vlans.yml
with_items: "{{vlan_members | default([])}}"
when: minigraph_vlans | length >0

- name: Flush vlan ips route
command: ip route flush {{generated_ips[0].split('/')[0]}}/32
become: yes
when: minigraph_vlans | length >0

- name: Add vlan ips route
command: ip route add {{generated_ips[0].split('/')[0]}}/32 dev {{minigraph_vlan_interfaces[0]['attachto']}}
become: yes
when: minigraph_vlans | length >0

- name: "Update ARP entry on DUT"
shell: ping {{minigraph_vlan_interfaces[0]['addr']}} -c 5
delegate_to: "{{ptf_host}}"
when: minigraph_vlans | length >0

- debug: msg="{{test_ports}}"

#****************************************#
# Start tests #
#****************************************#

- block:
- name: Choose random port for testing
include: roles/test/tasks/pfc_wd/choose_test_port.yml

- name: Test PFC WD configuration validation.
vars:
pfc_wd_template: roles/test/templates/pfc_wd_config.j2
include: roles/test/tasks/pfc_wd/config_test/config_test.yml

- name: Test PFC WD Functional tests.
vars:
pfc_wd_template: roles/test/templates/pfc_wd_config.j2
peer_device: "{{ neighbors[pfc_wd_test_port]['peerdevice'] }}"
include: roles/test/tasks/pfc_wd/functional_test/functional_test.yml
with_dict: "{{test_ports}}"

- name: Test PFC WD Timer accuracy.
include: roles/test/tasks/pfc_wd/functional_test/check_timer_accuracy_test.yml

- name: Test PFC WD extreme case when all ports have storm
include: roles/test/tasks/pfc_wd/functional_test/storm_all_test.yml
Expand Down
3 changes: 3 additions & 0 deletions ansible/roles/test/tasks/pfc_wd/config_test/config_test.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
- set_fact:
pfc_wd_test_port: "{{test_ports.keys()[0]}}"

- name: Generate config file for forward action test.
vars:
pfc_wd_interface_list: "{{ pfc_wd_test_port }}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
r, ".* Port counter .* not implemented"
r, ".* Port counter .* not supported"
r, ".* Invalid port counter .*"
r, ".* Unknown stat.*"
r, ".* snmpd .*"
r, ".* Trying to remove nonexisting queue from flex counter .*"
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Verify timers
- set_fact:
pfc_wd_test_port: "{{test_ports.keys()[0]}}"

- block:
- name: Apply config with proper timers to {{ pfc_wd_test_port }}.
vars:
command_to_run: "pfcwd start --action drop --restoration-time {{ pfc_wd_restore_time }} {{ ports }} {{ pfc_wd_detect_time }}"
errors_expected: false
include: roles/test/tasks/run_command_with_log_analyzer.yml

- name: Enable routing from mgmt interface to localhost
sysctl:
name: net.ipv4.conf.eth0.route_localnet
value: 1
sysctl_set: yes
become: true

# Cannot use iptables module, because it does not support to_destination in 2.0
- name: Add iptables rule to forward syslog packets from mgmt interface to localhost
shell: "iptables -t nat -I PREROUTING -p udp -d {{ansible_eth0_ipv4_addr}} --dport 514 -j DNAT --to-destination 127.0.0.1:514"
become: true

- set_fact:
detect_time_list: []
restore_time_list: []

- set_fact:
pfc_frames_number: 300000

- name: Calculate detection and restoration timings
include: roles/test/tasks/pfc_wd/functional_test/timer_test.yml
with_sequence: start=1 end=20

- debug:
var: "{{item}}"
with_items:
- detect_time_list
- restore_time_list

- name: Verify that real detection time is not greater than configured
fail:
msg: Real detection time is greater than configured
when: "{{(detect_time_list | sum)/20 > pfc_wd_detect_time + pfc_wd_poll_time}}"

- name: Verify that real detection time is not less than configured
fail:
msg: Real detection time is less than configured
when: "{{(detect_time_list | sum)/20 < pfc_wd_detect_time}}"

- name: Verify that real restoration time is not less than configured
fail:
msg: Real restoration time is less than configured
when: "{{(restore_time_list | sum)/20 < pfc_wd_restore_time}}"

- name: Verify that real restoration time is less than configured
fail:
msg: Real restoration time is greater than configured
when: "{{(restore_time_list | sum)/20 > pfc_wd_restore_time + pfc_wd_poll_time}}"

always:
- name: Clean up config
vars:
command_to_run: "pfcwd stop"
errors_expected: false
include: roles/test/tasks/run_command_with_log_analyzer.yml
Loading