| # |
| # test-common |
| # |
| # Common set of definitions and functions to help with driving VLANd |
| # in testing |
| # |
| # This specifically depends on *gawk* for the 2d arrays used in |
| # check_test_step() at the bottom |
| |
| TOPDIR=$(dirname $0)/.. |
| |
| # Default settings |
| if [ "$VERBOSE"x = ""x ] ; then |
| VERBOSE=0 |
| fi |
| if [ "$LOGVERBOSE"x = ""x ] ; then |
| LOGVERBOSE=$(($VERBOSE + 1)) |
| fi |
| if [ "$HOSTS"x = ""x ] ; then |
| HOSTS="panda01 panda02 panda03 arndale01 arndale02 arndale03 arndale04 imx5301 imx5302 imx5303" |
| fi |
| if [ "$SWITCHES"x = ""x ] ; then |
| SWITCHES="vlandswitch01 vlandswitch02 vlandswitch03 vlandswitch04 vlandswitch05" |
| fi |
| |
| LAST_COMMAND="" |
| |
| # Topology definitions - how are the test machines connected? |
| panda01_SWITCH_PORT="vlandswitch01:Gi1/0/2" |
| panda02_SWITCH_PORT="vlandswitch02:fa25" |
| panda03_SWITCH_PORT="vlandswitch03:gi25" |
| arndale01_SWITCH_PORT="vlandswitch01:Gi1/0/3" |
| arndale02_SWITCH_PORT="vlandswitch02:fa2" |
| arndale03_SWITCH_PORT="vlandswitch03:gi2" |
| arndale04_SWITCH_PORT="vlandswitch04:Gi1/0/3" |
| imx5301_SWITCH_PORT="vlandswitch05:1/0/21" |
| imx5302_SWITCH_PORT="vlandswitch05:1/0/22" |
| imx5303_SWITCH_PORT="vlandswitch04:Gi1/0/2" |
| |
| # Function for output; write text to our logfile and (optionally) the |
| # terminal, with timestamp for sorting. |
| _log () { |
| DATE=$(date -u +%F/%H:%M:%S.%N) |
| if [ "${LOGFILE}"x = ""x ] ; then |
| LOGFILE=$0.log |
| fi |
| LEVEL=$1 |
| shift |
| if [ $VERBOSE -gt $LEVEL ] ; then |
| echo "${DATE}: $@" >&2 # Use stderr so we don't confuse |
| # anybody reading our output |
| fi |
| if [ $LOGVERBOSE -gt $LEVEL ] ; then |
| echo " ${DATE}: $@" >> ${LOGFILE} |
| fi |
| } |
| |
| log () { |
| _log 0 $@ |
| } |
| |
| vlog () { |
| _log 1 $@ |
| } |
| |
| vvlog () { |
| _log 2 $@ |
| } |
| |
| # Run a vland admin command, and optionally log both the full text of |
| # the command and its output |
| run_admin_command () { |
| ADMIN="python $TOPDIR/vland-admin" |
| vlog "Running \"$ADMIN $@\"" |
| LAST_COMMAND="$@" |
| RESULT=$($ADMIN $@) |
| vlog " Result is \"$RESULT\"" |
| echo $RESULT |
| } |
| |
| verify_host_is_base () { |
| HOST=$1 |
| PORT_ID_VAR=${HOST}_PORT_ID |
| PORT_ID=${!PORT_ID_VAR} |
| CURRENT_VLAN_ID=$(run_admin_command get_port_current_vlan --port_id $PORT_ID) |
| CURRENT_VLAN_TAG=$(run_admin_command show_vlan_tag --vlan_id $CURRENT_VLAN_ID) |
| BASE_VLAN_ID=$(run_admin_command get_port_base_vlan --port_id $PORT_ID) |
| BASE_VLAN_TAG=$(run_admin_command show_vlan_tag --vlan_id $BASE_VLAN_ID) |
| vlog "$HOST" |
| vlog " is on port ID $PORT_ID" |
| vlog " which is on VLAN ID $CURRENT_VLAN_ID, tag $CURRENT_VLAN_TAG" |
| vlog " and should be on base VLAN ID $BASE_VLAN_ID, tag $BASE_VLAN_TAG" |
| if [ $CURRENT_VLAN_ID == $BASE_VLAN_ID ] ; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| verify_all_hosts_are_base () { |
| # Check that all the machines are correctly on their base VLANs |
| for host in $HOSTS; do |
| verify_host_is_base $host |
| if [ $? -ne 0 ] ; then |
| return 1 |
| fi |
| done |
| } |
| |
| all_hosts () { |
| COMMAND="$@" |
| for HOST in ${HOSTS}; do |
| vvlog "Running on ${HOST}:: ${COMMAND}" |
| ssh linaro@${HOST} "${COMMAND}" |
| done |
| } |
| |
| start_logging () { |
| log "Starting logging on hosts" |
| all_hosts "echo HOSTS=\\\"$HOSTS\\\" > test-config" |
| } |
| |
| stop_logging () { |
| log "Stopping logging on hosts" |
| all_hosts "rm -f test-config" |
| } |
| |
| grab_logs () { |
| log "Grabbing logs" |
| all_hosts "cat /tmp/ping-log*" |
| } |
| |
| clear_logs () { |
| log "Clearing old logs on hosts" |
| all_hosts "rm -f /tmp/ping-log*" |
| } |
| |
| pause () { |
| log "Pausing $1 seconds for systems to settle and/or log results" |
| sleep $1 |
| } |
| |
| cleanup () { |
| error=$? |
| if [ $error -ne 0 ] ; then |
| _log -1 "Test script aborted with error $error - check logs for the failure" |
| _log -1 " Last VLANd command appears to be \"$LAST_COMMAND\"" |
| fi |
| } |
| |
| list_test_steps () { |
| sort -u ${LOGFILE} | awk ' |
| /CHECK.*START/ { |
| gsub("^.*CHECK ","") |
| gsub(" START.*$","") |
| start[$0]=1 |
| } |
| /CHECK.*END/ { |
| gsub("^.*CHECK ","") |
| gsub(" END.*$","") |
| if(start[$0] == 1) { |
| print $0 |
| start[$0] = 0 |
| } |
| }' |
| } |
| |
| check_test_steps () { |
| OK=1 |
| for STEP in $(list_test_steps); do |
| log "Checking connectivity results for ${STEP}: " |
| RESULT=$(check_test_step ${STEP}) |
| log " $RESULT" |
| case "$RESULT" in |
| PASS*) |
| ;; # all good, do nothing |
| FAIL*) |
| echo " $STEP failed: $RESULT" |
| log " $STEP failed: $RESULT" |
| OK=0 |
| ;; |
| esac |
| done |
| if [ $OK -eq 1 ] ; then |
| echo " PASS" |
| log "PASS" |
| else |
| echo " FAIL" |
| log "FAIL" |
| false |
| fi |
| |
| # Now clean up the log file |
| sort -u ${LOGFILE} > ${LOGFILE}.1 |
| mv -f ${LOGFILE}.1 ${LOGFILE} |
| } |
| |
| check_test_step () { |
| STEP=$1 |
| sort -u ${LOGFILE} | awk -v STEP=$1 " |
| BEGIN { fails = \"\" } |
| /CHECK $STEP START/ { running=1 } |
| /CHECK $STEP END/ { running=0 } |
| /CHECK $STEP CHECK/ { |
| for( i = 4; i <= NF; i++) { |
| num_mach = split(\$i, mach_list, \":\") |
| for (j = 2; j <= num_mach; j++) { |
| test[mach_list[1]][mach_list[j]] = 1 |
| } |
| } |
| } |
| /UP/ { |
| if(running) { |
| OK=0 |
| for (group in test) { |
| if (test[group][\$2] && test[group][\$4]) { |
| OK=1 |
| success++ |
| } |
| } |
| if (OK == 0) { |
| fails = sprintf(\"%s{BAD UP: %s %s to %s} \",fails,\$1,\$2,\$4) |
| fail++ |
| } |
| } |
| } |
| /DOWN/ { |
| if(running) { |
| OK=1 |
| for (group in test) { |
| if (test[group][\$2] && test[group][\$4]) { |
| fails = sprintf(\"%s{BAD DOWN: %s %s to %s (%s)} \",fails,\$1,\$2,\$4,group) |
| OK=0 |
| fail++ |
| } |
| } |
| if (OK == 1) { |
| success++ |
| } |
| } |
| } |
| END { |
| if (fail > 0) { |
| printf(\"FAIL: success %d, fail %d (%s)\n\", success, fail, fails) |
| } else { |
| printf(\"PASS: success %d, fail %d\n\", success, fail) |
| } |
| } |
| " |
| } |
| |
| trap cleanup 0 |
| |
| ##################### |
| # |
| # MAIN CODE STARTS HERE |
| # |
| ##################### |
| |
| echo "Running test $NAME:" |
| echo " ($DESCRIPTION)" |
| echo " Logging to ${LOGFILE}" |
| |
| # Startup check |
| STATUS=$(run_admin_command status) |
| log $STATUS |
| |
| # Preload some data - what are the switch IDs and port IDs of the |
| # various things in our test setup? |
| for SWITCH in $SWITCHES; do |
| export ${SWITCH}_ID=$(run_admin_command lookup_switch_by_name --name $SWITCH) |
| done |
| |
| # Generate more detailed data for the hosts by asking VLANd what the |
| # IDs are for each port, etc. |
| for host in $HOSTS; do |
| SWITCH_PORT_VAR=${host}_SWITCH_PORT |
| SW=${!SWITCH_PORT_VAR%%:*} |
| SW_VAR=${SW}_ID |
| SW_ID=${!SW_VAR} |
| PORT_NAME=${!SWITCH_PORT_VAR##*:} |
| PORT_ID=$(run_admin_command lookup_port_by_switch_and_name --switch_id $SW_ID --name $PORT_NAME) |
| export ${host}_PORT_ID=${PORT_ID} |
| CURRENT_VLAN_ID=$(run_admin_command get_port_current_vlan --port_id $PORT_ID) |
| export ${host}_CURRENT_VLANID=$CURRENT_VLAN_ID |
| CURRENT_VLAN_TAG=$(run_admin_command show_vlan_tag --vlan_id $CURRENT_VLAN_ID) |
| export ${host}_CURRENT_VLAN_TAG=$CURRENT_VLAN_TAG |
| done |