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 # Start lldpd on each VM
276 run R1 libtool execute src
/daemon
/lldpd
-M 1 -L \
$PWD/src
/client
/lldpcli
277 run R2 libtool execute src
/daemon
/lldpd
-M 2 -L \
$PWD/src
/client
/lldpcli
278 run R3 libtool execute src
/daemon
/lldpd
-M 3 -L \
$PWD/src
/client
/lldpcli
281 run R1 libtool execute src
/client
/lldpcli show neighbor detail
282 run R2 libtool execute src
/client
/lldpcli show neighbor detail
283 run R3 libtool execute src
/client
/lldpcli show neighbor detail
285 run R2 ip link add link iface2 name iface2.450
type vlan id
450
286 run R2 ip link
set up dev iface2.450
287 run R2 ip link add link iface2 name iface2.451
type vlan id
451
288 run R2 ip link
set up dev iface2.451
289 run R2 ip link add link iface2 name iface2.452
type vlan id
452
290 run R2 ip link
set up dev iface2.452
292 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface2
294 run R2 ip link del iface2.451
296 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface2
298 run R3 ip link
set down dev iface2
299 run R3 ip link
set down dev iface3
300 run R3 ip link
set iface2 master bond0
301 run R3 ip link
set iface3 master bond0
302 run R3 ip link
set up dev bond0
304 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface4
305 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface5
306 # Add a VLAN on top of bond
307 run R3 ip link add link bond0 name bond0.453
type vlan id
453
308 run R3 ip link
set up dev bond0.453
310 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface4
312 run R2 brctl addbr br0
313 run R2 brctl addif br0 iface3
314 run R2 ip link
set up dev br0
316 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface3
318 conf
="libtool execute src/client/lldpcli configure ports iface2"
319 run R2
$conf lldp custom-tlv oui
33,44,55 subtype
44 oui-info
45,45,45,45,45
320 run R2
$conf med location elin
911
321 run R2
$conf med location coordinate latitude
48.58667N longitude
2.2014E altitude
117.47 m datum WGS84
322 run R2
$conf med power pd
source pse priority high value
5000
323 run R2
$conf dot3 power pse supported enabled paircontrol powerpairs spare class class-3
325 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface2
326 # Configuration should stay when port go down and up
327 run R2 ip link
set down dev iface2
329 run R2 ip link
set up dev iface2
331 run R1 libtool execute src
/client
/lldpcli show neighbor detail ports iface2
336 for pid
in $TMP/*.pid
; do
337 kill -15 -$
(cat $pid) 2> /dev
/null || true
340 for pid
in $TMP/*.pid
; do
341 kill -9 -$
(cat $pid) 2> /dev
/null || true
347 export STATE
=${STATE:-BEGIN}
351 log_info_msg
"initrd started"
353 export PATH
=/usr
/local
/bin
:/usr
/bin
:/bin
:/sbin
:/usr
/local
/sbin
:/usr
/sbin
356 [ ! -f /modules
] ||
{
357 log_info_msg
"Loading modules"
361 log_begin_msg
"Setup root file system"
362 mount
-n -t tmpfs tmpfs
/tmp
-o rw
365 mkdir
/tmp
/target
/overlay
366 mount
-n -t 9p rootshare
/tmp
/target
/overlay
-o trans
=virtio
,version
=9p2000.u
,ro
367 mount
-n -t proc proc
/tmp
/target
/overlay
/proc
368 mount
-n -t sysfs sys
/tmp
/target
/overlay
/sys
369 log_ok_msg
"Root file system setup"
371 log_begin_msg
"Clean /tmp and /run"
372 for fs
in /run
/var
/run
/var
/tmp
/var
/log
/tmp
/mnt
; do
373 if [ -d /tmp
/target
/overlay
$fs ] && [ ! -h /tmp
/target
/overlay
$fs ]; then
374 mount
-t tmpfs tmpfs
/tmp
/target
/overlay
$fs -o rw
,nosuid
,nodev
377 log_ok_msg
"/tmp, /run and others are clean"
379 log_begin_msg
"Mount /lib/modules"
380 mount
-t 9p moduleshare
/tmp
/target
/overlay
/lib
/modules
-o trans
=virtio
,version
=9p2000.L
,access
=0,ro || \
381 log_error_msg
"Unable to mount /lib/modules"
382 log_ok_msg
"/root and /lib/modules mounted"
384 log_begin_msg
"Mount /mnt/lab"
385 mkdir
/tmp
/target
/overlay
/mnt
/lab
386 mount
-t 9p labshare
/tmp
/target
/overlay
/mnt
/lab
-o trans
=virtio
,version
=9p2000.L
,access
=any
,rw || \
387 log_error_msg
"Unable to mount /mnt/lab"
388 log_ok_msg
"/mnt/lab mounted"
390 log_begin_msg
"Mount /tmp/lab"
391 mkdir
/tmp
/target
/overlay
/tmp
/lab
392 mount
-t 9p tmpshare
/tmp
/target
/overlay
/tmp
/lab
-o trans
=virtio
,version
=9p2000.L
,access
=any
,rw || \
393 log_error_msg
"Unable to mount /tmp/lab"
394 log_ok_msg
"/tmp/lab mounted"
396 log_info_msg
"Change root"
397 export STATE
=CHROOTED
398 exec chroot
/tmp
/target
/overlay
/mnt
/lab
/tests
/integration-tests
402 log_begin_msg
"Starting udev"
404 mount
-n -o size
=10M
,mode
=0755 -t devtmpfs devtmpfs
/dev
405 udevadm info
--cleanup-db
406 for udev
in /lib
/systemd
/systemd-udevd
/usr
/lib
/systemd
/systemd-udevd $
(command -v udevd
2> /dev
/null
); do
407 [ ! -x $udev ] ||
break
410 udevadm trigger
--action=add
412 log_ok_msg
"udev started"
414 log_info_msg
"Setup interfaces"
415 modprobe dummy
2>/dev
/null || true
416 modprobe bonding
2>/dev
/null || true
417 sleep 0.5 # Some interfaces may take some time to appear
418 # Rename all interfaces to "predictable" and "non-colliding"
419 # name. We don't have if we have eth* or ens* interfaces. Let
420 # take a totally different naming convention.
422 for iface
in $
(echo /sys
/bus
/virtio
/drivers
/virtio_net
/*/net
/*); do
423 ip link
set name iface
$nb dev
${iface##*/}
426 for intf
in /sys
/class
/net
/*; do
427 intf
=$
(basename $intf)
428 ip a l dev
$intf 2> /dev
/null
>/dev
/null ||
continue
429 ip link
set up dev
$intf
432 log_info_msg
"Setup IP addresses"
435 ip
-4 addr add
192.0.2.15/24 dev iface1
436 ip
-6 addr add
2001:db8
::cafe
:15/64 dev iface1
439 ip
-4 addr add
192.0.2.16/24 dev iface1
440 ip
-6 addr add
2001:db8
::cafe
:16/64 dev iface1
443 ip
-4 addr add
192.0.2.17/24 dev iface1
444 ip
-6 addr add
2001:db8
::cafe
:17/64 dev iface1
447 rtmon
file /mnt
/lab
/tests
/${uts}.rtmon
&
448 process_commands
2>&1 |
tee /mnt
/lab
/tests
/${uts}.output
453 [ $
(id
-u) != 0 ] ||
{
454 log_error_msg
"You should not run this as root"
457 PROGNAME
="$(readlink -f "$0")"
459 ROOT
="$(readlink -f "${ROOT:-/}")" # Root filesystem
460 KERNEL
="$(readlink -f "${1:-/boot/vmlinuz-$(uname -r)}")" # Kernel
461 PATH
="$PATH":/usr
/local
/sbin
:/usr
/sbin
:/sbin
462 [ $# -lt 1 ] ||
shift
477 NET
=1,2,3,4,5 start_vm R1
478 NET
=1,2,3 start_vm R2
479 NET
=1,4,5 start_vm R3
484 -e 's/^\(Interface:.*, Time: 0 day\).*/\1/' \
485 -e 's/^\( SysDescr:\).*/\1/' \
486 -e 's/^\( Hardware Revision: pc-i440fx\).*/\1/' \
487 -e 's/^\( Software Revision: \).*/\1/' \
488 -e 's/^\( Firmware Revision: \).*/\1/' \
489 R1.output
> R1.output.redacted
490 diff -u @srcdir@
/R1.expected R1.output.redacted || \
491 log_error_msg
"Unexpected differences"
493 log_info_msg
"End of tests"
499 # indent-tabs-mode: nil