3 # Integration tests for lldpd. Those tests only run on Linux. They
4 # spawn several VM and connect them together, then check lldpcli
5 # results to see if everything is in order.
7 # lldpd should be configure with:
8 # ../configure --localstatedir=/var --sysconfdir=/etc --prefix=/usr CFLAGS="-O0 -g"
32 log_begin_msg
"Checking kernel version"
33 [ -f "$KERNEL" ] || log_error_msg
"Unable to find kernel $KERNEL"
34 [ -r "$KERNEL" ] || log_error_msg
"Kernel $KERNEL is not readable.\n Try \`setfacl -m u:$USER:r $KERNEL'"
36 # A recent version of `file` is able to extract the
37 # information. Since it is not widely available, let use some hack
41 gunzip \\\037\\\213\\\010 xy
42 unxz \\\3757zXZ\\\000 abcde
44 unlzma \\\135\\\0\\\0\\\0 xxx
46 while read cmd sig1 sig2
; do
49 *) poss
=$
(tr "${sig1}\n${sig2}" "\n${sig2}=" < "$KERNEL" | grep -abo "^${sig2}" || true
) ;;
51 [ -n "$poss" ] ||
continue
54 tail -c+$pos "$KERNEL" |
$cmd 2> /dev
/null |
strings -20 | \
55 grep ^Linux.version |
head -1
59 [ -n "$VERSION" ] || log_error_msg
"Unable to determine version for $KERNEL"
60 VERSION
="${VERSION#Linux version }"
61 VERSION
="${VERSION%% *}"
62 log_ok_msg
"Found kernel $VERSION"
64 log_begin_msg
"Check kernel configuration"
65 CONFIG
="$(dirname $KERNEL)/config-$VERSION"
66 [ -f "$CONFIG" ] || log_error_msg
"Unable to find configuration file $CONFIG"
67 cat <<EOF | while read el; do
79 grep -qx "CONFIG_$el" $CONFIG || log_error_msg
"Kernel not configured with CONFIG_$el"
82 log_begin_msg
"Search for modules"
83 for dir
in "$(dirname $KERNEL)/lib/modules/$VERSION" "/lib/modules/$VERSION"; do
84 [ -d $dir ] ||
continue
88 if [ -z "$MODULES" ]; then
89 log_warn_msg
"Unable to find module directory"
91 log_ok_msg
"Modules are in $MODULES"
95 check_dependencies
() {
96 log_begin_msg
"Checking if dependencies are present"
103 which $exec 2> /dev
/null
> /dev
/null || log_error_msg
"$exec is not installed"
105 log_ok_msg
"All dependencies are met"
110 trap "ret=$? ; cleanup" EXIT
111 log_info_msg
"TMP is $TMP"
117 log_begin_msg
"Setup switch $nb"
118 cat <<EOF > "$TMP/switch-$nb.conf"
119 plugin/add /usr/lib/vde2/plugins/pdump.so
120 pdump/filename $TMP/switch-$nb.pcap
125 --sock "$TMP/switch-$nb.sock" --mgmt "$TMP/switch-management-$nb.sock" \
126 --rcfile "$TMP/switch-$nb.conf" --hub --daemon --pidfile "$TMP/switch-$nb.pid"
127 # Management socket can be used with:
128 # socat - UNIX-CONNECT:"$TMP/switch-management-$nb.sock"
129 log_ok_msg
"Switch $nb started"
133 log_begin_msg
"Build initrd"
137 # Copy busybox and eventually insmod
139 busybox
--list |
grep -qFx insmod || bins
="$bins insmod"
141 install -D "$(which $bin)" ${DESTDIR}/bin
/$bin
142 for x
in $
(ldd
"$(which $bin)" 2> /dev
/null |
sed -e '
145 /=>/ {s/.*=>[[:blank:]]*\([^[:blank:]]*\).*/\1/};
146 s/[[:blank:]]*\([^[:blank:]]*\) (.*)/\1/' 2>/dev
/null
); do
147 [ -f "${DESTDIR}/$x" ] ||
install -D "$x" "${DESTDIR}/$x"
152 for applet
in $
(${DESTDIR}/bin
/busybox
--list); do
153 ln -s busybox
${DESTDIR}/bin
/${applet}
157 [ -z "$MODULES" ] ||
{
158 modules
="9pnet_virtio 9p virtio_pci $UNION"
159 for mod
in $modules; do
160 modprobe
--all --set-version="${VERSION}" -d ${MODULES}/..
/..
/.. \
161 --ignore-install --quiet --show-depends $mod > /dev
/null ||
{
162 log_warn_msg
"Unable to find module $mod"
163 log_begin_msg
"Continue building initrd"
165 modprobe
--all --set-version="${VERSION}" -d ${MODULES}/..
/..
/.. \
166 --ignore-install --quiet --show-depends $mod |
167 while read prefix kmod options
; do
168 [ "${prefix}" = "insmod" ] ||
continue
169 grep -qFw "$kmod" ${DESTDIR}/modules
2> /dev
/null ||
{
170 install -D "$kmod" "${DESTDIR}/${kmod}"
171 echo $prefix $kmod $options >> ${DESTDIR}/modules
178 cp "$PROGNAME" ${DESTDIR}/init
184 (cd "${DESTDIR}" && find . |
cpio --quiet -R 0:0 -o -H newc |
gzip > $TMP/initrd.gz
)
186 log_ok_msg
"initrd built in $TMP/initrd.gz"
190 # But, not random in fact
193 mac
=$
(echo $name-$net |
sha1sum | \
194 awk '{print "50:54:" substr($1,0,2) ":" substr($1, 2, 2) ":" substr($1, 4, 2) ":" substr($1, 6, 2)}')
206 mac
=$
(random_mac
$name $net)
207 netargs
="$netargs -net nic,model=virtio,macaddr=$mac,vlan=$net"
208 netargs
="$netargs -net vde,sock=$TMP/switch-$net.sock,vlan=$net"
212 log_info_msg
"Start VM $name"
213 # /root is mounted with version 9p2000.u to allow access to /dev,
214 # /sys and to mount new partitions over them. This is not the case
218 -nodefconfig -nodefaults \
222 -chardev file,id
=charserial0
,path
=$name.console \
223 -device isa-serial
,chardev
=charserial0
,id
=serial0 \
225 -fsdev local,security_model
=passthrough
,id
=fsdev-root
,path
=${ROOT} \
226 -device virtio-9p-pci
,id
=fs-root
,fsdev
=fsdev-root
,mount_tag
=rootshare \
227 -fsdev local,security_model
=none
,id
=fsdev-lab
,path
=@top_builddir@ \
228 -device virtio-9p-pci
,id
=fs-lab
,fsdev
=fsdev-lab
,mount_tag
=labshare \
229 -fsdev local,security_model
=none
,id
=fsdev-tmp
,path
=${TMP} \
230 -device virtio-9p-pci
,id
=fs-tmp
,fsdev
=fsdev-tmp
,mount_tag
=tmpshare \
231 -fsdev local,security_model
=none
,id
=fsdev-modules
,path
=${MODULES}/..
,readonly \
232 -device virtio-9p-pci
,id
=fs-modules
,fsdev
=fsdev-modules
,mount_tag
=moduleshare \
236 -initrd $TMP/initrd.gz \
237 -append "uts=$name console=ttyS0 panic=1 TERM=$TERM quiet" \
240 echo $
! > "$TMP/vm-$name.pid"
246 log_info_msg
"$r: execute $*"
247 printf "%s\n" "$*" > $TMP/${r}.
command
249 while [ -f $TMP/${r}.
command ]; do
253 log_error_msg
"Timeout while executing command on $r"
260 log_info_msg
"Waiting for commands"
261 cmd
=/tmp
/lab
/${uts}.
command
264 while [ ! -f $cmd ]; do
267 log_info_msg
"Execute command $(head -1 $cmd)"
269 log_info_msg
"End of command: $?"
275 # Set the environment
276 run R2 ip link
set dev iface2
alias "SecondInterface"
277 # Start lldpd on each VM
278 run R1 .
/libtool execute src
/daemon
/lldpd
-M 1 -L \
$PWD/src
/client
/lldpcli
279 run R2 .
/libtool execute src
/daemon
/lldpd
-M 2 -L \
$PWD/src
/client
/lldpcli
280 run R3 .
/libtool execute src
/daemon
/lldpd
-M 3 -L \
$PWD/src
/client
/lldpcli
283 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail
284 run R2 .
/libtool execute src
/client
/lldpcli show neighbor detail
285 run R3 .
/libtool execute src
/client
/lldpcli show neighbor detail
287 run R2 ip link add link iface2 name iface2.450
type vlan id
450
288 run R2 ip link
set up dev iface2.450
289 run R2 ip link add link iface2 name iface2.451
type vlan id
451
290 run R2 ip link
set up dev iface2.451
291 run R2 ip link add link iface2 name iface2.452
type vlan id
452
292 run R2 ip link
set up dev iface2.452
294 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface2
296 run R2 ip link del iface2.451
298 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface2
300 run R3 ip link
set down dev iface2
301 run R3 ip link
set down dev iface3
302 run R3 ip link
set iface2 master bond0
303 run R3 ip link
set iface3 master bond0
304 run R3 ip link
set up dev bond0
306 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface4
307 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface5
308 # Add a VLAN on top of bond
309 run R3 ip link add link bond0 name bond0.453
type vlan id
453
310 run R3 ip link
set up dev bond0.453
312 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface4
314 run R2 brctl addbr br0
315 run R2 brctl addif br0 iface3
316 run R2 ip link
set up dev br0
318 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface3
320 conf
="./libtool execute src/client/lldpcli configure ports iface2"
321 run R2
$conf lldp custom-tlv oui
33,44,55 subtype
44 oui-info
45,45,45,45,45
322 run R2
$conf med location elin
911
323 run R2
$conf med location coordinate latitude
48.58667N longitude
2.2014E altitude
117.47 m datum WGS84
324 run R2
$conf med power pd
source pse priority high value
5000
325 run R2
$conf dot3 power pse supported enabled paircontrol powerpairs spare class class-3
327 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface2
328 # Configuration should stay when port go down and up
329 run R2 ip link
set down dev iface2
331 run R2 ip link
set up dev iface2
333 run R1 .
/libtool execute src
/client
/lldpcli show neighbor detail ports iface2
338 for pid
in $TMP/*.pid
; do
339 kill -15 -$
(cat $pid) 2> /dev
/null || true
342 for pid
in $TMP/*.pid
; do
343 kill -9 -$
(cat $pid) 2> /dev
/null || true
349 export STATE
=${STATE:-BEGIN}
353 log_info_msg
"initrd started"
355 export PATH
=/usr
/local
/bin
:/usr
/bin
:/bin
:/sbin
:/usr
/local
/sbin
:/usr
/sbin
358 [ ! -f /modules
] ||
{
359 log_info_msg
"Loading modules"
363 log_begin_msg
"Setup root file system"
364 mount
-n -t tmpfs tmpfs
/tmp
-o rw
367 mkdir
/tmp
/target
/overlay
368 mount
-n -t 9p rootshare
/tmp
/target
/overlay
-o trans
=virtio
,version
=9p2000.u
,ro
369 mount
-n -t proc proc
/tmp
/target
/overlay
/proc
370 mount
-n -t sysfs sys
/tmp
/target
/overlay
/sys
371 log_ok_msg
"Root file system setup"
373 log_begin_msg
"Clean /tmp and /run"
374 for fs
in /run
/var
/run
/var
/tmp
/var
/log
/tmp
/mnt
; do
375 if [ -d /tmp
/target
/overlay
$fs ] && [ ! -h /tmp
/target
/overlay
$fs ]; then
376 mount
-t tmpfs tmpfs
/tmp
/target
/overlay
$fs -o rw
,nosuid
,nodev
379 log_ok_msg
"/tmp, /run and others are clean"
381 log_begin_msg
"Mount /lib/modules"
382 mount
-t 9p moduleshare
/tmp
/target
/overlay
/lib
/modules
-o trans
=virtio
,version
=9p2000.L
,access
=0,ro || \
383 log_error_msg
"Unable to mount /lib/modules"
384 log_ok_msg
"/root and /lib/modules mounted"
386 log_begin_msg
"Mount /mnt/lab"
387 mkdir
/tmp
/target
/overlay
/mnt
/lab
388 mount
-t 9p labshare
/tmp
/target
/overlay
/mnt
/lab
-o trans
=virtio
,version
=9p2000.L
,access
=any
,rw || \
389 log_error_msg
"Unable to mount /mnt/lab"
390 log_ok_msg
"/mnt/lab mounted"
392 log_begin_msg
"Mount /tmp/lab"
393 mkdir
/tmp
/target
/overlay
/tmp
/lab
394 mount
-t 9p tmpshare
/tmp
/target
/overlay
/tmp
/lab
-o trans
=virtio
,version
=9p2000.L
,access
=any
,rw || \
395 log_error_msg
"Unable to mount /tmp/lab"
396 log_ok_msg
"/tmp/lab mounted"
398 log_info_msg
"Change root"
399 export STATE
=CHROOTED
400 exec chroot
/tmp
/target
/overlay
/mnt
/lab
/tests
/integration-tests
404 log_begin_msg
"Starting udev"
406 mount
-n -o size
=10M
,mode
=0755 -t devtmpfs devtmpfs
/dev
407 udevadm info
--cleanup-db
408 for udev
in /lib
/systemd
/systemd-udevd
/usr
/lib
/systemd
/systemd-udevd $
(command -v udevd
2> /dev
/null
); do
409 [ ! -x $udev ] ||
break
412 udevadm trigger
--action=add
414 log_ok_msg
"udev started"
416 log_info_msg
"Setup interfaces"
417 modprobe dummy
2>/dev
/null || true
418 modprobe bonding
2>/dev
/null || true
419 sleep 0.5 # Some interfaces may take some time to appear
420 # Rename all interfaces to "predictable" and "non-colliding"
421 # name. We don't have if we have eth* or ens* interfaces. Let
422 # take a totally different naming convention.
424 for iface
in $
(echo /sys
/bus
/virtio
/drivers
/virtio_net
/*/net
/*); do
425 ip link
set name iface
$nb dev
${iface##*/}
428 for intf
in /sys
/class
/net
/*; do
429 intf
=$
(basename $intf)
430 ip a l dev
$intf 2> /dev
/null
>/dev
/null ||
continue
431 ip link
set up dev
$intf
434 log_info_msg
"Setup IP addresses"
437 ip
-4 addr add
192.0.2.15/24 dev iface1
438 ip
-6 addr add
2001:db8
::cafe
:15/64 dev iface1
441 ip
-4 addr add
192.0.2.16/24 dev iface1
442 ip
-6 addr add
2001:db8
::cafe
:16/64 dev iface1
445 ip
-4 addr add
192.0.2.17/24 dev iface1
446 ip
-6 addr add
2001:db8
::cafe
:17/64 dev iface1
449 rtmon
file /mnt
/lab
/tests
/${uts}.rtmon
&
450 process_commands
2>&1 |
tee /mnt
/lab
/tests
/${uts}.output
455 [ $
(id
-u) != 0 ] ||
{
456 log_error_msg
"You should not run this as root"
459 PROGNAME
="$(readlink -f "$0")"
461 ROOT
="$(readlink -f "${ROOT:-/}")" # Root filesystem
462 KERNEL
="$(readlink -f "${1:-/boot/vmlinuz-$(uname -r)}")" # Kernel
463 PATH
="$PATH":/usr
/local
/sbin
:/usr
/sbin
:/sbin
464 [ $# -lt 1 ] ||
shift
479 NET
=1,2,3,4,5 start_vm R1
480 NET
=1,2,3 start_vm R2
481 NET
=1,4,5 start_vm R3
486 -e 's/^\(Interface:.*, Time: 0 day\).*/\1/' \
487 -e 's/^\( SysDescr:\).*/\1/' \
488 -e 's/^\( Hardware Revision: pc-i440fx\).*/\1/' \
489 -e 's/^\( Software Revision: \).*/\1/' \
490 -e 's/^\( Firmware Revision: \).*/\1/' \
491 -e 's/command \.\/libtool /command libtool /' \
492 R1.output
> R1.output.redacted
493 diff -u @srcdir@
/R1.expected R1.output.redacted || \
494 log_error_msg
"Unexpected differences"
496 log_info_msg
"End of tests"
502 # indent-tabs-mode: nil