From: Vincent Bernat Date: Sun, 10 Jan 2016 12:34:32 +0000 (+0100) Subject: build: add some integration tests X-Git-Tag: 0.9.0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8cd1f2d07e047eb6673892fde447144a130f5b7e;p=thirdparty%2Flldpd.git build: add some integration tests --- diff --git a/README.md b/README.md index dde80a97..fc253ab3 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,12 @@ that: mv *.pcap inputs afl-fuzz -i inputs -o outputs ./decode @@ +There is a general test suite with `make check`. It's also possible to +run integration tests with `./tests/integration-tests`. Those are not +very flexible and may or may not work depending on your platform. Also +check the content of `tests/lldpcli.conf`. It's a configuration file +that should cover all commands present in lldpcli. + Embedding --------- diff --git a/tests/Makefile.am b/tests/Makefile.am index b06d7f81..e8c41fc0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -52,3 +52,9 @@ decode_SOURCES = decode.c \ endif MOSTLYCLEANFILES = *.pcap + +TEMPLATES = integration-tests +EXTRA_DIST = integration-tests.in R1.expected +CLEANFILES = $(TEMPLATES) +integration-tests: integration-tests.in +include $(top_srcdir)/edit.am diff --git a/tests/R1.expected b/tests/R1.expected new file mode 100644 index 00000000..fc346a90 --- /dev/null +++ b/tests/R1.expected @@ -0,0 +1,497 @@ +[∗] Waiting for commands. +[∗] Execute command libtool execute src/daemon/lldpd -M 1 -L $PWD/src/client/lldpcli. +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface1, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Station, on + Port: + PortID: mac 50:54:b3:3c:2c:36 + PortDescr: iface1 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +Interface: iface1, via: LLDP, RID: 2, Time: 0 day + Chassis: + ChassisID: mac 50:54:07:79:57:69 + SysName: R3 + SysDescr: + MgmtIP: 192.0.2.17 + MgmtIP: 2001:db8::cafe:17 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Tel, on + Capability: Station, on + Port: + PortID: mac 50:54:07:79:57:69 + PortDescr: iface1 + LLDP-MED: + Device Type: Communication Device Endpoint (Class III) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +Interface: iface2, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Station, on + Port: + PortID: mac 50:54:0e:ec:6e:77 + PortDescr: iface2 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +Interface: iface3, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Station, on + Port: + PortID: mac 50:54:5e:ed:e2:df + PortDescr: iface3 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +Interface: iface4, via: LLDP, RID: 2, Time: 0 day + Chassis: + ChassisID: mac 50:54:07:79:57:69 + SysName: R3 + SysDescr: + MgmtIP: 192.0.2.17 + MgmtIP: 2001:db8::cafe:17 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Tel, on + Capability: Station, on + Port: + PortID: mac 50:54:30:01:78:dd + PortDescr: iface2 + LLDP-MED: + Device Type: Communication Device Endpoint (Class III) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +Interface: iface5, via: LLDP, RID: 2, Time: 0 day + Chassis: + ChassisID: mac 50:54:07:79:57:69 + SysName: R3 + SysDescr: + MgmtIP: 192.0.2.17 + MgmtIP: 2001:db8::cafe:17 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Tel, on + Capability: Station, on + Port: + PortID: mac 50:54:ef:f4:f5:bf + PortDescr: iface3 + LLDP-MED: + Device Type: Communication Device Endpoint (Class III) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface2. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface2, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Station, on + Port: + PortID: mac 50:54:0e:ec:6e:77 + PortDescr: iface2 + VLAN: 450 iface2.450 + VLAN: 451 iface2.451 + VLAN: 452 iface2.452 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface2. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface2, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Station, on + Port: + PortID: mac 50:54:0e:ec:6e:77 + PortDescr: iface2 + VLAN: 450 iface2.450 + VLAN: 452 iface2.452 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface4. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface4, via: LLDP, RID: 2, Time: 0 day + Chassis: + ChassisID: mac 50:54:07:79:57:69 + SysName: R3 + SysDescr: + MgmtIP: 192.0.2.17 + MgmtIP: 2001:db8::cafe:17 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Tel, on + Capability: Station, off + Port: + PortID: mac 50:54:30:01:78:dd + PortDescr: iface2 + Port is aggregated. PortAggregID: 6 + LLDP-MED: + Device Type: Communication Device Endpoint (Class III) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface5. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface5, via: LLDP, RID: 2, Time: 0 day + Chassis: + ChassisID: mac 50:54:07:79:57:69 + SysName: R3 + SysDescr: + MgmtIP: 192.0.2.17 + MgmtIP: 2001:db8::cafe:17 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Tel, on + Capability: Station, off + Port: + PortID: mac 50:54:ef:f4:f5:bf + PortDescr: iface3 + Port is aggregated. PortAggregID: 6 + LLDP-MED: + Device Type: Communication Device Endpoint (Class III) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface4. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface4, via: LLDP, RID: 2, Time: 0 day + Chassis: + ChassisID: mac 50:54:07:79:57:69 + SysName: R3 + SysDescr: + MgmtIP: 192.0.2.17 + MgmtIP: 2001:db8::cafe:17 + Capability: Bridge, off + Capability: Router, off + Capability: Wlan, off + Capability: Tel, on + Capability: Station, off + Port: + PortID: mac 50:54:30:01:78:dd + PortDescr: iface2 + Port is aggregated. PortAggregID: 6 + VLAN: 453 bond0.453 + LLDP-MED: + Device Type: Communication Device Endpoint (Class III) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface3. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface3, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, on + Capability: Router, off + Capability: Wlan, off + Capability: Station, off + Port: + PortID: mac 50:54:5e:ed:e2:df + PortDescr: iface3 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface2. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface2, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, on + Capability: Router, off + Capability: Wlan, off + Capability: Station, off + Port: + PortID: mac 50:54:0e:ec:6e:77 + PortDescr: iface2 + MDI Power: supported: yes, enabled: yes, pair control: yes + Device type: PSE + Power pairs: spare + Class: class 3 + VLAN: 450 iface2.450 + VLAN: 452 iface2.452 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + LLDP-MED Location Identification: Type: Coordinates, Geoid: WGS84 + Latitude: 48.58666N + Longitude: 2.2013E + Altitude: m 117.46 + LLDP-MED Location Identification: Type: ELIN + ECS ELIN: 911 + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 + UnknownTLVs: + TLV: OUI: 33,44,55, SubType: 44, Len: 5 45,45,45,45,45 +------------------------------------------------------------------------------- +[∗] End of command: 0. +[∗] Execute command libtool execute src/client/lldpcli show neighbor detail ports iface2. +------------------------------------------------------------------------------- +LLDP neighbors: +------------------------------------------------------------------------------- +Interface: iface2, via: LLDP, RID: 1, Time: 0 day + Chassis: + ChassisID: mac 50:54:b3:3c:2c:36 + SysName: R2 + SysDescr: + MgmtIP: 192.0.2.16 + MgmtIP: 2001:db8::cafe:16 + Capability: Bridge, on + Capability: Router, off + Capability: Wlan, off + Capability: Station, off + Port: + PortID: mac 50:54:0e:ec:6e:77 + PortDescr: iface2 + MDI Power: supported: yes, enabled: yes, pair control: yes + Device type: PSE + Power pairs: spare + Class: class 3 + VLAN: 450 iface2.450 + VLAN: 452 iface2.452 + LLDP-MED: + Device Type: Media Endpoint (Class II) + Capability: Capabilities + Capability: Policy + Capability: Location + Capability: MDI/PSE + Capability: MDI/PD + Capability: Inventory + LLDP-MED Location Identification: Type: Coordinates, Geoid: WGS84 + Latitude: 48.58666N + Longitude: 2.2013E + Altitude: m 117.46 + LLDP-MED Location Identification: Type: ELIN + ECS ELIN: 911 + Inventory: + Hardware Revision: pc-i440fx + Software Revision: + Firmware Revision: + Manufacturer: QEMU + Model: Standard PC (i440FX + PIIX, 1996 + UnknownTLVs: + TLV: OUI: 33,44,55, SubType: 44, Len: 5 45,45,45,45,45 +------------------------------------------------------------------------------- +[∗] End of command: 0. diff --git a/tests/integration-tests.in b/tests/integration-tests.in new file mode 100755 index 00000000..bf8664f6 --- /dev/null +++ b/tests/integration-tests.in @@ -0,0 +1,547 @@ +#!/bin/sh + +# Integration tests for lldpd. Those tests only run on Linux. They +# spawn several VM and connect them together, then check lldpcli +# results to see if everything is in order. + +# lldpd should be configure with: +# ../configure --localstatedir=/var --sysconfdir=/etc --prefix=/usr CFLAGS="-O0 -g" + +LABNAME=lldpd + +set -e + +log_begin_msg () { + echo "[…] $1... " +} +log_ok_msg () { + echo "[✔] $1." +} +log_warn_msg () { + echo "[⚡] $1!" +} +log_error_msg () { + echo "[✘] $1!" + exit 1 +} +log_info_msg () { + echo "[∗] $1." +} + +check_kernel() { + log_begin_msg "Checking kernel version" + [ -f "$KERNEL" ] || log_error_msg "Unable to find kernel $KERNEL" + [ -r "$KERNEL" ] || log_error_msg "Kernel $KERNEL is not readable.\n Try \`setfacl -m u:$USER:r $KERNEL'" + + # A recent version of `file` is able to extract the + # information. Since it is not widely available, let use some hack + # method. + VERSION=$(cat < /dev/null | strings -20 | \ + grep ^Linux.version | head -1 + done + done | head -1) + + [ -n "$VERSION" ] || log_error_msg "Unable to determine version for $KERNEL" + VERSION="${VERSION#Linux version }" + VERSION="${VERSION%% *}" + log_ok_msg "Found kernel $VERSION" + + log_begin_msg "Check kernel configuration" + CONFIG="$(dirname $KERNEL)/config-$VERSION" + [ -f "$CONFIG" ] || log_error_msg "Unable to find configuration file $CONFIG" + cat < /dev/null > /dev/null || log_error_msg "$exec is not installed" + done + log_ok_msg "All dependencies are met" +} + +setup_tmp () { + TMP=$(mktemp -d) + trap "ret=$? ; cleanup" EXIT + log_info_msg "TMP is $TMP" +} + +# Run our lab in tmux +setup_screen() { + if [ -z "$TMUX" ] || [ x"$(tmux list-panes -F '#{session_name}')" != x"$LABNAME" ]; then + unset TMUX + exec tmux new-session -s "$LABNAME" -n main \ + "env ROOT=$ROOT VERSION=$VERSION LINUX=$LINUX $PROGNAME $PROGARGS || read" + fi + sleep 1 + tmux set-option -q prefix C-b + tmux set-option -q set-remain-on-exit on + tmux bind-key r respawn-window +} + +# Setup a VDE switch +setup_switch() { + nb=$1 ; shift + log_begin_msg "Setup switch $nb" + cat < "$TMP/switch-$nb.conf" +plugin/add /usr/lib/vde2/plugins/pdump.so +pdump/filename $TMP/switch-$nb.pcap +pdump/buffered 0 +pdump/active 1 +EOF + start-stop-daemon -b --no-close --make-pidfile --pidfile "$TMP/switch-$nb.pid" \ + --start --startas $(which vde_switch) -- \ + --sock "$TMP/switch-$nb.sock" --mgmt "$TMP/switch-management-$nb.sock" \ + --rcfile "$TMP/switch-$nb.conf" --hub + # Management socket can be used with: + # socat - UNIX-CONNECT:"$TMP/switch-management-$nb.sock" + log_ok_msg "Switch $nb started" +} + +setup_initrd () { + log_begin_msg "Build initrd" + DESTDIR=$TMP/initrd + mkdir -p $DESTDIR + + # Copy busybox and eventually insmod + bins="busybox" + busybox --list | grep -qFx insmod || bins="$bins insmod" + for bin in $bins; do + install -D "$(which $bin)" ${DESTDIR}/bin/$bin + for x in $(ldd "$(which $bin)" 2> /dev/null | sed -e ' + /\//!d; + /linux-gate/d; + /=>/ {s/.*=>[[:blank:]]*\([^[:blank:]]*\).*/\1/}; + s/[[:blank:]]*\([^[:blank:]]*\) (.*)/\1/' 2>/dev/null); do + [ -f "${DESTDIR}/$x" ] || install -D "$x" "${DESTDIR}/$x" + done + done + + # Configure busybox + for applet in $(${DESTDIR}/bin/busybox --list); do + ln -s busybox ${DESTDIR}/bin/${applet} + done + + # Add modules + [ -z "$MODULES" ] || { + modules="9pnet_virtio 9p virtio_pci $UNION" + for mod in $modules; do + modprobe --all --set-version="${VERSION}" -d ${MODULES}/../../.. \ + --ignore-install --quiet --show-depends $mod > /dev/null || { + log_warn_msg "Unable to find module $mod" + log_begin_msg "Continue building initrd" + } + modprobe --all --set-version="${VERSION}" -d ${MODULES}/../../.. \ + --ignore-install --quiet --show-depends $mod | + while read prefix kmod options ; do + [ "${prefix}" = "insmod" ] || continue + grep -qFw "$kmod" ${DESTDIR}/modules 2> /dev/null || { + install -D "$kmod" "${DESTDIR}/${kmod}" + echo $prefix $kmod $options >> ${DESTDIR}/modules + } + done + done + } + + # Copy this program + cp "$PROGNAME" ${DESTDIR}/init + + # Create /tmp + mkdir ${DESTDIR}/tmp + + # Build initrd + (cd "${DESTDIR}" && find . | cpio --quiet -R 0:0 -o -H newc | gzip > $TMP/initrd.gz) + + log_ok_msg "initrd built in $TMP/initrd.gz" +} + +random_mac () { + # But, not random in fact + name=$1 + net=$2 + mac=$(echo $name-$net | sha1sum | \ + awk '{print "50:54:" substr($1,0,2) ":" substr($1, 2, 2) ":" substr($1, 4, 2) ":" substr($1, 6, 2)}') + echo $mac +} + +start_vm () { + name=$1 + shift + + netargs="" + saveifs="$IFS" + IFS=, + for net in $NET; do + mac=$(random_mac $name $net) + netargs="$netargs -net nic,model=virtio,macaddr=$mac,vlan=$net" + netargs="$netargs -net vde,sock=$TMP/switch-$net.sock,vlan=$net" + done + IFS="$saveifs" + + log_info_msg "Start VM $name" + # /root is mounted with version 9p2000.u to allow access to /dev, + # /sys and to mount new partitions over them. This is not the case + # for 9p2000.L. + cat < "$TMP/vm-$name.exec" +#!/bin/sh + echo + exec start-stop-daemon --make-pidfile --pidfile "$TMP/vm-$name.pid" \ + --start --startas $(which qemu-system-x86_64) -- \ + -enable-kvm \ + -nodefconfig -nodefaults \ + -display none \ + -m ${MEM:-128M} \ + \ + -chardev stdio,id=charserial0,signal=off \ + -device isa-serial,chardev=charserial0,id=serial0 \ + -chardev socket,id=charserial1,path=$TMP/vm-$name-serial.pipe,server,nowait \ + -device isa-serial,chardev=charserial1,id=serial1 \ + \ + -chardev socket,id=con0,path=$TMP/vm-$name-console.pipe,server,nowait \ + -mon chardev=con0,mode=readline,default \ + \ + -fsdev local,security_model=passthrough,id=fsdev-root,path=${ROOT} \ + -device virtio-9p-pci,id=fs-root,fsdev=fsdev-root,mount_tag=rootshare \ + -fsdev local,security_model=none,id=fsdev-lab,path=${PWD} \ + -device virtio-9p-pci,id=fs-lab,fsdev=fsdev-lab,mount_tag=labshare \ + -fsdev local,security_model=none,id=fsdev-tmp,path=${TMP} \ + -device virtio-9p-pci,id=fs-tmp,fsdev=fsdev-tmp,mount_tag=tmpshare \ + -fsdev local,security_model=none,id=fsdev-modules,path=${MODULES}/..,readonly \ + -device virtio-9p-pci,id=fs-modules,fsdev=fsdev-modules,mount_tag=moduleshare \ + \ + -gdb unix:$TMP/vm-$name-gdb.pipe,server,nowait \ + -kernel $KERNEL \ + -no-reboot \ + -initrd $TMP/initrd.gz \ + -append "uts=$name console=ttyS0 panic=1 TERM=$TERM quiet" \ + $netargs \ + $@ +EOF + log_info_msg "GDB server listening on $TMP/vm-$name-gdb.pipe" + log_info_msg "monitor listening on $TMP/vm-$name-console.pipe" + log_info_msg "ttyS1 listening on $TMP/vm-$name-serial.pipe" + chmod +x "$TMP/vm-$name.exec" + tmux new-window -n $name "$TMP/vm-$name.exec" + tmux select-window -t ":^" +} + +display_help() { + cat < $TMP/${r}.command + n=0 + while [ -f $TMP/${r}.command ]; do + sleep 1 + n=$((n + 1)) + [ $n -le 15 ] || { + log_error_msg "Timeout while executing command on $r" + } + done +} + +process_commands() { + cd /mnt/lab + log_info_msg "Waiting for commands" + cmd=/tmp/lab/${uts}.command + set +e + while true; do + while [ ! -f $cmd ]; do + sleep 1 + done + log_info_msg "Execute command $(head -1 $cmd)" + sh $cmd + log_info_msg "End of command: $?" + rm $cmd + done +} + +start_tests() { + # Start lldpd on each VM + run R1 libtool execute src/daemon/lldpd -M 1 -L \$PWD/src/client/lldpcli + run R2 libtool execute src/daemon/lldpd -M 2 -L \$PWD/src/client/lldpcli + run R3 libtool execute src/daemon/lldpd -M 3 -L \$PWD/src/client/lldpcli + sleep 2 + # Query neighbors + run R1 libtool execute src/client/lldpcli show neighbor detail + run R2 libtool execute src/client/lldpcli show neighbor detail + run R3 libtool execute src/client/lldpcli show neighbor detail + # Add some VLAN + run R2 ip link add link iface2 name iface2.450 type vlan id 450 + run R2 ip link set up dev iface2.450 + run R2 ip link add link iface2 name iface2.451 type vlan id 451 + run R2 ip link set up dev iface2.451 + run R2 ip link add link iface2 name iface2.452 type vlan id 452 + run R2 ip link set up dev iface2.452 + sleep 2 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface2 + # Remove one + run R2 ip link del iface2.451 + sleep 2 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface2 + # Add a bond + run R3 ip link set down dev iface2 + run R3 ip link set down dev iface3 + run R3 ip link set iface2 master bond0 + run R3 ip link set iface3 master bond0 + run R3 ip link set up dev bond0 + sleep 2 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface4 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface5 + # Add a VLAN on top of bond + run R3 ip link add link bond0 name bond0.453 type vlan id 453 + run R3 ip link set up dev bond0.453 + sleep 2 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface4 + # Add a bridge + run R2 brctl addbr br0 + run R2 brctl addif br0 iface3 + run R2 ip link set up dev br0 + sleep 2 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface3 + # Modify some TLV + conf="libtool execute src/client/lldpcli configure ports iface2" + run R2 $conf lldp custom-tlv oui 33,44,55 subtype 44 oui-info 45,45,45,45,45 + run R2 $conf med location elin 911 + run R2 $conf med location coordinate latitude 48.58667N longitude 2.2014E altitude 117.47 m datum WGS84 + run R2 $conf med power pd source pse priority high value 5000 + run R2 $conf dot3 power pse supported enabled paircontrol powerpairs spare class class-3 + sleep 2 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface2 + # Configuration should stay when port go down and up + run R2 ip link set down dev iface2 + sleep 2 + run R2 ip link set up dev iface2 + sleep 5 + run R1 libtool execute src/client/lldpcli show neighbor detail ports iface2 +} + +cleanup() { + set +e + for pid in $TMP/*.pid; do + kill -15 -$(cat $pid) 2> /dev/null || true + done + sleep 1 + for pid in $TMP/*.pid; do + kill -9 -$(cat $pid) 2> /dev/null || true + done + rm -rf $TMP + tmux kill-session -t $LABNAME +} + +# FSM +export STATE=${STATE:-BEGIN} +case $$,$STATE in + 1,BEGIN) + # In initrd + log_info_msg "initrd started" + hostname ${uts} + export PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/local/sbin:/usr/sbin + export HOME=/root + + [ ! -f /modules ] || { + log_info_msg "Loading modules" + . /modules + } + + log_begin_msg "Setup root file system" + mount -n -t tmpfs tmpfs /tmp -o rw + mkdir /tmp/target + mkdir /tmp/target/ro + mkdir /tmp/target/overlay + mount -n -t 9p rootshare /tmp/target/overlay -o trans=virtio,version=9p2000.u,ro + mount -n -t proc proc /tmp/target/overlay/proc + mount -n -t sysfs sys /tmp/target/overlay/sys + log_ok_msg "Root file system setup" + + log_begin_msg "Clean /tmp and /run" + for fs in /run /var/run /var/tmp /var/log /tmp /mnt; do + if [ -d /tmp/target/overlay$fs ] && [ ! -h /tmp/target/overlay$fs ]; then + mount -t tmpfs tmpfs /tmp/target/overlay$fs -o rw,nosuid,nodev + fi + done + log_ok_msg "/tmp, /run and others are clean" + + log_begin_msg "Mount /lib/modules" + mount -t 9p moduleshare /tmp/target/overlay/lib/modules -o trans=virtio,version=9p2000.L,access=0,ro || \ + log_error_msg "Unable to mount /lib/modules" + log_ok_msg "/root and /lib/modules mounted" + + log_begin_msg "Mount /mnt/lab" + mkdir /tmp/target/overlay/mnt/lab + mount -t 9p labshare /tmp/target/overlay/mnt/lab -o trans=virtio,version=9p2000.L,access=any,rw || \ + log_error_msg "Unable to mount /mnt/lab" + log_ok_msg "/mnt/lab mounted" + + log_begin_msg "Mount /tmp/lab" + mkdir /tmp/target/overlay/tmp/lab + mount -t 9p tmpshare /tmp/target/overlay/tmp/lab -o trans=virtio,version=9p2000.L,access=any,rw || \ + log_error_msg "Unable to mount /tmp/lab" + log_ok_msg "/tmp/lab mounted" + + log_info_msg "Change root" + export STATE=CHROOTED + exec chroot /tmp/target/overlay /mnt/lab/integration-tests + ;; + + 1,CHROOTED) + log_begin_msg "Starting udev" + udev_log=err + mount -n -o size=10M,mode=0755 -t devtmpfs devtmpfs /dev + udevadm info --cleanup-db + for udev in /lib/systemd/systemd-udevd /usr/lib/systemd/systemd-udevd $(command -v udevd 2> /dev/null); do + [ ! -x $udev ] || break + done + $udev --daemon + udevadm trigger --action=add + udevadm settle + log_ok_msg "udev started" + + log_info_msg "Setup interfaces" + modprobe dummy 2>/dev/null || true + modprobe bonding 2>/dev/null || true + sleep 0.5 # Some interfaces may take some time to appear + # Rename all interfaces to "predictable" and "non-colliding" + # name. We don't have if we have eth* or ens* interfaces. Let + # take a totally different naming convention. + nb=1 + for iface in $(echo /sys/bus/virtio/drivers/virtio_net/*/net/*); do + ip link set name iface$nb dev ${iface##*/} + nb=$((nb + 1)) + done + for intf in /sys/class/net/*; do + intf=$(basename $intf) + ip a l dev $intf 2> /dev/null >/dev/null || continue + ip link set up dev $intf + done + + log_info_msg "Setup IP addresses" + case $uts in + R1) + ip -4 addr add 192.0.2.15/24 dev iface1 + ip -6 addr add 2001:db8::cafe:15/64 dev iface1 + ;; + R2) + ip -4 addr add 192.0.2.16/24 dev iface1 + ip -6 addr add 2001:db8::cafe:16/64 dev iface1 + ;; + R3) + ip -4 addr add 192.0.2.17/24 dev iface1 + ip -6 addr add 2001:db8::cafe:17/64 dev iface1 + ;; + esac + process_commands 2>&1 | tee /mnt/lab/${uts}.output + ;; + + *,BEGIN) + # Initial state + [ $(id -u) != 0 ] || { + log_error_msg "You should not run this as root" + exit 1 + } + PROGNAME="$(readlink -f "$0")" + PROGARGS="$@" + ROOT="$(readlink -f "${ROOT:-/}")" # Root filesystem + KERNEL="$(readlink -f "${1:-/boot/vmlinuz-$(uname -r)}")" # Kernel + PATH="$PATH":/usr/local/sbin:/usr/sbin:/sbin + [ $# -lt 1 ] || shift + + check_kernel + check_dependencies + setup_screen + setup_tmp + setup_initrd + + setup_switch 1 + setup_switch 2 + setup_switch 3 + setup_switch 4 + setup_switch 5 + sleep 0.3 + + NET=1,2,3,4,5 start_vm R1 + NET=1,2,3 start_vm R2 + NET=1,4,5 start_vm R3 + + display_help + start_tests + + sed \ + -e 's/^\(Interface:.*, Time: 0 day\).*/\1/' \ + -e 's/^\( SysDescr:\).*/\1/' \ + -e 's/^\( Hardware Revision: pc-i440fx\).*/\1/' \ + -e 's/^\( Software Revision: \).*/\1/' \ + -e 's/^\( Firmware Revision: \).*/\1/' \ + R1.output > R1.output.redacted + diff -u ../tests/R1.expected R1.output.redacted || \ + log_warn_msg "Unexpected differences" + + log_info_msg "End of tests, press enter to exit." + read a + ;; +esac + +# Local Variables: +# mode: sh +# indent-tabs-mode: nil +# sh-basic-offset: 4 +# End: