aboutsummaryrefslogtreecommitdiff
path: root/test/test-common
blob: ddc79860542cdd0f50909d7c78bfdf390f6e4798 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#
# 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/admin.py"
    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