From 0377a379a34b70980a0596fc0fd16de873683acc Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Thu, 27 Oct 2016 16:16:41 +0300 Subject: [PATCH 1/4] ansible tests: Add test for the neighbour MAC change update This is the test for the issue https://github.com/Azure/SONiC/issues/19 --- .../roles/test/files/neighbour/neigh_test.sh | 115 ++++++++++++++++++ ansible/roles/test/tasks/neighbour.yml | 24 ++++ ansible/roles/test/tasks/sonic.yml | 4 + 3 files changed, 143 insertions(+) create mode 100755 ansible/roles/test/files/neighbour/neigh_test.sh create mode 100644 ansible/roles/test/tasks/neighbour.yml diff --git a/ansible/roles/test/files/neighbour/neigh_test.sh b/ansible/roles/test/files/neighbour/neigh_test.sh new file mode 100755 index 00000000000..f4f30eb031b --- /dev/null +++ b/ansible/roles/test/files/neighbour/neigh_test.sh @@ -0,0 +1,115 @@ +#!/bin/bash -ex + +# Test for the issue #19 (https://github.com/Azure/SONiC/issues/19) +# H/w config: +# +--------+ +-------+ +# | Host X<---->Y DUT | +# +--------+ +-------+ +# +# S/w config: +# iface - the name of the interface X +# dut_host - ip/hostname of the DUT management interface +# dut_connected_ip - ip/hostname on the interface Y +# dut_user - user on DUT (capable to run docker, has Host in known_hosts +# Call syntax: +# neigh_test.sh admin arc-switch1027 20.0.0.1 20.0.0.2 +# $1 $2 $3 $4 + +# default values +iface=eth2 +iface_ip=20.0.0.2 +dut_host=arc-switch1027 +dut_connected_ip=20.0.0.1 +dut_user=admin + +mac1=00:c0:ca:c0:1a:05 +mac2=00:c0:ca:c0:1a:06 + +if [ ! -z $4 ]; then + iface_ip=$4 +fi + +if [ ! -z $3 ]; then + dut_connected_ip=$3 +fi + +if [ ! -z $2 ]; then + dut_host=$2 +fi + +if [ ! -z $1 ]; then + dut_user=$1 +fi + +mac1=00:c0:ca:c0:1a:05 +mac2=00:c0:ca:c0:1a:06 + +function ping_dut() +{ + ping ${dut_connected_ip} -c 3 -I ${iface} >/dev/null; +} + +# get mac of given interface +# $1 interface to get mac on +# ret: mac as string +function get_mac() +{ + local mac=`ifconfig ${1} | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'` + #read mac < /sys/class/net/${1}/address + #ifconfig ${1} | grep ether | awk '{print $2}' net-tools > 2.0 + echo ${mac}; +} + +# set mac on local interface +# $1 - interface +# $2 - mac to set +function set_mac() +{ + ifconfig ${1} down; ifconfig ${1} hw ether ${2}; ifconfig ${1} up; +} + +# get neighbour mac from SAI DB for given ip +# $1 - ip of the neighbour +# ret: 1 - not found +# 0 - success +function get_neighbour_mac() +{ + # convert ip to hex format (20.0.0.2 -> 14000002) + iface_ip_hex=`printf '%02X' ${iface_ip//./ }` + # grep redis DB to find a key holding data for the neighbour with this IP + key=`ssh ${dut_user}@${dut_host} "bash -c 'docker exec database redis-cli -n 1 KEYS ASIC* ' | grep -i ${iface_ip_hex}"` + #echo $key; echo + # NEIGHBOUR_DST_MAC_ADDRESS attribute code is 0, so using key 00000000 + mac=`ssh ${dut_user}@${dut_host} "bash -c 'docker exec database redis-cli -n 1 HGET ${key} 00000000'"` + echo ${mac} +} + +# save host's mac +host_mac=$(get_mac ${iface}) + +# populate neighbour #1 +set_mac ${iface} ${mac1} +ping_dut + +# check neighbour #1 +neigh_mac=$(get_neighbour_mac ${iface_ip}) +if [ $neigh_mac != ${mac1//:/} ]; then + echo "Neighbour mac set failed" + exit 1 +fi + +# populate neighbour #2 (ip will remain the same) +set_mac ${iface} ${mac2} +ping_dut + +# chech neighbour's mac changed +neigh_mac=$(get_neighbour_mac ${iface_ip}) +if [ $neigh_mac != ${mac2//:/} ]; then + echo "Neighbour mac update failed" + exit 1 +fi + +# restore host mac address +set_mac ${iface} ${host_mac} + +exit 0 diff --git a/ansible/roles/test/tasks/neighbour.yml b/ansible/roles/test/tasks/neighbour.yml new file mode 100644 index 00000000000..dc1399d76d3 --- /dev/null +++ b/ansible/roles/test/tasks/neighbour.yml @@ -0,0 +1,24 @@ +# Test run example: +# ansible-playbook -i inventory --limit switch-host test_sonic.yml -b -e "ptf_host=ptf-1" --tags neighbour + +- name: Change DUT interface IP to test IP address + become: yes + command: /sbin/ifconfig Ethernet0 20.0.0.1 netmask 255.255.255.0 + +- name: Change host interface IP to test IP address + become: yes + command: /sbin/ifconfig eth0 20.0.0.2 netmask 255.255.255.0 + delegate_to: "{{ ptf_host }}" + +- name: copy neighbour test files + become: yes + copy: src=roles/test/files/neighbour/neigh_test.sh dest=/root mode=u=rx + delegate_to: "{{ ptf_host }}" + +- name: Check if switch handles neighbour MAC address change + become: true + shell: /root/neigh_test.sh admin {{ inventory_hostname }} 20.0.0.1 20.0.0.2 + register: result + failed_when: result.rc != 0 + delegate_to: "{{ ptf_host }}" + diff --git a/ansible/roles/test/tasks/sonic.yml b/ansible/roles/test/tasks/sonic.yml index 5dfea64ae11..52abc9d4931 100644 --- a/ansible/roles/test/tasks/sonic.yml +++ b/ansible/roles/test/tasks/sonic.yml @@ -1,3 +1,7 @@ +- name: Neighbour tests + include: neighbour.yml + tags: neighbour + - name: Test LLDP include: lldp.yml tags: lldp From bd9bc8adf0aeefcb526190659dc6e2220b9ad3ad Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Fri, 28 Oct 2016 17:42:07 +0300 Subject: [PATCH 2/4] Renamed neighbour.yml -> neighbour-mac.yml --- ansible/roles/test/tasks/{neighbour.yml => neighbour-mac.yml} | 0 ansible/roles/test/tasks/sonic.yml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename ansible/roles/test/tasks/{neighbour.yml => neighbour-mac.yml} (100%) diff --git a/ansible/roles/test/tasks/neighbour.yml b/ansible/roles/test/tasks/neighbour-mac.yml similarity index 100% rename from ansible/roles/test/tasks/neighbour.yml rename to ansible/roles/test/tasks/neighbour-mac.yml diff --git a/ansible/roles/test/tasks/sonic.yml b/ansible/roles/test/tasks/sonic.yml index 52abc9d4931..b38b3516730 100644 --- a/ansible/roles/test/tasks/sonic.yml +++ b/ansible/roles/test/tasks/sonic.yml @@ -1,5 +1,5 @@ -- name: Neighbour tests - include: neighbour.yml +- name: Neighbor mac change test + include: neighbour-mac.yml tags: neighbour - name: Test LLDP From 021360f25e9a234d6887ec7b2417c529999e82d2 Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Fri, 28 Oct 2016 17:45:12 +0300 Subject: [PATCH 3/4] Rewrote test to use ansible script only --- .../roles/test/files/neighbour/neigh_test.sh | 115 ------------------ ansible/roles/test/tasks/neighbour-mac.yml | 82 +++++++++++-- 2 files changed, 72 insertions(+), 125 deletions(-) delete mode 100755 ansible/roles/test/files/neighbour/neigh_test.sh diff --git a/ansible/roles/test/files/neighbour/neigh_test.sh b/ansible/roles/test/files/neighbour/neigh_test.sh deleted file mode 100755 index f4f30eb031b..00000000000 --- a/ansible/roles/test/files/neighbour/neigh_test.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/bash -ex - -# Test for the issue #19 (https://github.com/Azure/SONiC/issues/19) -# H/w config: -# +--------+ +-------+ -# | Host X<---->Y DUT | -# +--------+ +-------+ -# -# S/w config: -# iface - the name of the interface X -# dut_host - ip/hostname of the DUT management interface -# dut_connected_ip - ip/hostname on the interface Y -# dut_user - user on DUT (capable to run docker, has Host in known_hosts -# Call syntax: -# neigh_test.sh admin arc-switch1027 20.0.0.1 20.0.0.2 -# $1 $2 $3 $4 - -# default values -iface=eth2 -iface_ip=20.0.0.2 -dut_host=arc-switch1027 -dut_connected_ip=20.0.0.1 -dut_user=admin - -mac1=00:c0:ca:c0:1a:05 -mac2=00:c0:ca:c0:1a:06 - -if [ ! -z $4 ]; then - iface_ip=$4 -fi - -if [ ! -z $3 ]; then - dut_connected_ip=$3 -fi - -if [ ! -z $2 ]; then - dut_host=$2 -fi - -if [ ! -z $1 ]; then - dut_user=$1 -fi - -mac1=00:c0:ca:c0:1a:05 -mac2=00:c0:ca:c0:1a:06 - -function ping_dut() -{ - ping ${dut_connected_ip} -c 3 -I ${iface} >/dev/null; -} - -# get mac of given interface -# $1 interface to get mac on -# ret: mac as string -function get_mac() -{ - local mac=`ifconfig ${1} | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'` - #read mac < /sys/class/net/${1}/address - #ifconfig ${1} | grep ether | awk '{print $2}' net-tools > 2.0 - echo ${mac}; -} - -# set mac on local interface -# $1 - interface -# $2 - mac to set -function set_mac() -{ - ifconfig ${1} down; ifconfig ${1} hw ether ${2}; ifconfig ${1} up; -} - -# get neighbour mac from SAI DB for given ip -# $1 - ip of the neighbour -# ret: 1 - not found -# 0 - success -function get_neighbour_mac() -{ - # convert ip to hex format (20.0.0.2 -> 14000002) - iface_ip_hex=`printf '%02X' ${iface_ip//./ }` - # grep redis DB to find a key holding data for the neighbour with this IP - key=`ssh ${dut_user}@${dut_host} "bash -c 'docker exec database redis-cli -n 1 KEYS ASIC* ' | grep -i ${iface_ip_hex}"` - #echo $key; echo - # NEIGHBOUR_DST_MAC_ADDRESS attribute code is 0, so using key 00000000 - mac=`ssh ${dut_user}@${dut_host} "bash -c 'docker exec database redis-cli -n 1 HGET ${key} 00000000'"` - echo ${mac} -} - -# save host's mac -host_mac=$(get_mac ${iface}) - -# populate neighbour #1 -set_mac ${iface} ${mac1} -ping_dut - -# check neighbour #1 -neigh_mac=$(get_neighbour_mac ${iface_ip}) -if [ $neigh_mac != ${mac1//:/} ]; then - echo "Neighbour mac set failed" - exit 1 -fi - -# populate neighbour #2 (ip will remain the same) -set_mac ${iface} ${mac2} -ping_dut - -# chech neighbour's mac changed -neigh_mac=$(get_neighbour_mac ${iface_ip}) -if [ $neigh_mac != ${mac2//:/} ]; then - echo "Neighbour mac update failed" - exit 1 -fi - -# restore host mac address -set_mac ${iface} ${host_mac} - -exit 0 diff --git a/ansible/roles/test/tasks/neighbour-mac.yml b/ansible/roles/test/tasks/neighbour-mac.yml index dc1399d76d3..2c9849ccc43 100644 --- a/ansible/roles/test/tasks/neighbour-mac.yml +++ b/ansible/roles/test/tasks/neighbour-mac.yml @@ -1,24 +1,86 @@ +# docker exec -it syncd sx_api_port_speed_set_100G.py # Test run example: -# ansible-playbook -i inventory --limit switch-host test_sonic.yml -b -e "ptf_host=ptf-1" --tags neighbour +# ansible-playbook -i inventory --limit arc-switch1027 test_sonic.yml -b -e "ptf_host=ptf-1" --tags neighbour + +- set_fact: + host_if: eth0 + dut_if: Ethernet0 + host_ip: 20.0.0.2 + dut_ip: 20.0.0.1 + nei_mac1: 00:c0:ca:c0:1a:05 + nei_mac2: 00:c0:ca:c0:1a:06 - name: Change DUT interface IP to test IP address become: yes - command: /sbin/ifconfig Ethernet0 20.0.0.1 netmask 255.255.255.0 + command: /sbin/ifconfig {{ dut_if }} {{ dut_ip }} netmask 255.255.255.0 - name: Change host interface IP to test IP address become: yes - command: /sbin/ifconfig eth0 20.0.0.2 netmask 255.255.255.0 + command: /sbin/ifconfig {{ host_if }} {{ host_ip }} netmask 255.255.255.0 delegate_to: "{{ ptf_host }}" -- name: copy neighbour test files - become: yes - copy: src=roles/test/files/neighbour/neigh_test.sh dest=/root mode=u=rx +- name: Get host MAC + become: true + shell: ifconfig {{ host_if }} | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}' + register: host_mac + failed_when: host_mac.rc != 0 + delegate_to: "{{ ptf_host }}" + +- name: Set host MAC to pretend neighbour #1 + become: true + shell: ifconfig {{ host_if }} down; ifconfig {{ host_if }} hw ether {{ nei_mac1 }}; ifconfig {{ host_if }} up + register: set1 + failed_when: set1.rc != 0 delegate_to: "{{ ptf_host }}" -- name: Check if switch handles neighbour MAC address change +- name: Ping DUT to populate neighbour #1 become: true - shell: /root/neigh_test.sh admin {{ inventory_hostname }} 20.0.0.1 20.0.0.2 - register: result - failed_when: result.rc != 0 + shell: ping {{ dut_ip }} -c 3 -I {{ host_if }} + register: ping1 + failed_when: ping1.rc != 0 delegate_to: "{{ ptf_host }}" +- name: Get host ip in hex + become: true + shell: printf '%02x%02x%02x%02x' `echo {{ host_ip }} | sed 's/\./ /g'` + register: host_ip_hex + +- name: Get the SONiC DB key holding neighbour MAC for {{ host_ip_hex.stdout }} + become: true + shell: docker exec database redis-cli -n 1 KEYS ASIC* | grep -i {{ host_ip_hex.stdout }} + register: neighbour_key + failed_when: neighbour_key.rc != 0 + +- name: Check neighbour MAC on DUT. Should be {{ nei_mac1 }} + become: true + shell: docker exec database redis-cli -n 1 HGET {{ neighbour_key.stdout }} 00000000 + register: neighbour_mac + failed_when: neighbour_mac.rc != 0 + failed_when: neighbour_mac.stdout != "{{ nei_mac1 | regex_replace(':', '') }}" + +- name: Set host MAC to pretend neighbour #2 + become: true + shell: ifconfig {{ host_if }} down; ifconfig {{ host_if }} hw ether {{ nei_mac2 }}; ifconfig {{ host_if }} up + register: set2 + failed_when: set2.rc != 0 + delegate_to: "{{ ptf_host }}" + +- name: Ping DUT to populate neighbour #2 + become: true + shell: ping {{ dut_ip }} -c 3 -I {{ host_if }} + register: ping2 + failed_when: ping2.rc != 0 + delegate_to: "{{ ptf_host }}" + +- name: Get the SONiC DB key holding neighbour MAC for {{ host_ip_hex.stdout }} + become: true + shell: docker exec database redis-cli -n 1 KEYS ASIC* | grep -i {{ host_ip_hex.stdout }} + register: neighbour_key + failed_when: neighbour_key.rc != 0 + +- name: Check neighbour MAC on DUT. Should be {{ nei_mac2 }} + become: true + shell: docker exec database redis-cli -n 1 HGET {{ neighbour_key.stdout }} 00000000 + register: neighbour_mac + failed_when: neighbour_mac.rc != 0 + failed_when: neighbour_mac.stdout != "{{ nei_mac2 | regex_replace(':', '') }}" From 4fe3fbff115a2138be2b56a3b136bc37c0b58cce Mon Sep 17 00:00:00 2001 From: Andriy Moroz Date: Mon, 7 Nov 2016 14:28:09 +0200 Subject: [PATCH 4/4] Update the test to conform to the new SAI DB format --- ansible/roles/test/tasks/neighbour-mac.yml | 31 +++++++++------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/ansible/roles/test/tasks/neighbour-mac.yml b/ansible/roles/test/tasks/neighbour-mac.yml index 2c9849ccc43..d599b2cf408 100644 --- a/ansible/roles/test/tasks/neighbour-mac.yml +++ b/ansible/roles/test/tasks/neighbour-mac.yml @@ -7,8 +7,8 @@ dut_if: Ethernet0 host_ip: 20.0.0.2 dut_ip: 20.0.0.1 - nei_mac1: 00:c0:ca:c0:1a:05 - nei_mac2: 00:c0:ca:c0:1a:06 + nei_mac1: 00:C0:CA:C0:1A:05 + nei_mac2: 00:C0:CA:C0:1A:06 - name: Change DUT interface IP to test IP address become: yes @@ -40,23 +40,17 @@ failed_when: ping1.rc != 0 delegate_to: "{{ ptf_host }}" -- name: Get host ip in hex +- name: Get the SONiC DB key holding neighbour MAC for {{ host_ip }} become: true - shell: printf '%02x%02x%02x%02x' `echo {{ host_ip }} | sed 's/\./ /g'` - register: host_ip_hex - -- name: Get the SONiC DB key holding neighbour MAC for {{ host_ip_hex.stdout }} - become: true - shell: docker exec database redis-cli -n 1 KEYS ASIC* | grep -i {{ host_ip_hex.stdout }} + shell: docker exec database redis-cli -n 1 KEYS ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY* | grep {{ host_ip }} register: neighbour_key failed_when: neighbour_key.rc != 0 -- name: Check neighbour MAC on DUT. Should be {{ nei_mac1 }} +- name: Check neighbour MAC1 on DUT. Should be {{ nei_mac1 }} become: true - shell: docker exec database redis-cli -n 1 HGET {{ neighbour_key.stdout }} 00000000 + shell: docker exec database redis-cli -n 1 HGET '{{ neighbour_key.stdout }}' 'SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS' register: neighbour_mac - failed_when: neighbour_mac.rc != 0 - failed_when: neighbour_mac.stdout != "{{ nei_mac1 | regex_replace(':', '') }}" + failed_when: neighbour_mac.stdout != "{{ nei_mac1 }}" - name: Set host MAC to pretend neighbour #2 become: true @@ -72,15 +66,14 @@ failed_when: ping2.rc != 0 delegate_to: "{{ ptf_host }}" -- name: Get the SONiC DB key holding neighbour MAC for {{ host_ip_hex.stdout }} +- name: Get the SONiC DB key holding neighbour MAC for {{ host_ip }} become: true - shell: docker exec database redis-cli -n 1 KEYS ASIC* | grep -i {{ host_ip_hex.stdout }} + shell: docker exec database redis-cli -n 1 KEYS ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY* | grep {{ host_ip }} register: neighbour_key failed_when: neighbour_key.rc != 0 -- name: Check neighbour MAC on DUT. Should be {{ nei_mac2 }} +- name: Check neighbour MAC2 on DUT. Should be {{ nei_mac2 }} become: true - shell: docker exec database redis-cli -n 1 HGET {{ neighbour_key.stdout }} 00000000 + shell: docker exec database redis-cli -n 1 HGET '{{ neighbour_key.stdout }}' 'SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS' register: neighbour_mac - failed_when: neighbour_mac.rc != 0 - failed_when: neighbour_mac.stdout != "{{ nei_mac2 | regex_replace(':', '') }}" + failed_when: neighbour_mac.stdout != "{{ nei_mac2 }}"