[libvirt] [PATCH v2] [TCK] network: create networks and check for expected results

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Oct 25 16:31:43 UTC 2010



V2:
    - test cases for ipconfig, brctl added
    - fixed test data after after using iptables with -n

Derived from the nwfilter test program, this one works with libvirt's
networks. It creates networks from provided xml files and checks for
expected configuration in iptables, running processes and virsh output
using provided data files with commands to execute and the expected
results for after creating the network and after tearing it down
(*.post.dat). 3 tests are currently not passing due to a bug in
libvirt...

Signed-off-by: Stefan Berger<stefanb at us.ibm.com>

---
  Build.PL                                                   |    2
  scripts/networks/100-apply-verify-host.t                   |   10
  scripts/networks/networkApplyTest.sh                       |  343 +++++++++++++
  scripts/networks/networkxml2hostout/tck-testnet-1.dat      |   17
  scripts/networks/networkxml2hostout/tck-testnet-1.post.dat |    7
  scripts/networks/networkxml2hostout/tck-testnet-2.dat      |   14
  scripts/networks/networkxml2hostout/tck-testnet-2.post.dat |    7
  scripts/networks/networkxml2xmlin/tck-testnet-1.xml        |   12
  scripts/networks/networkxml2xmlin/tck-testnet-2.xml        |   12
  9 files changed, 423 insertions(+), 1 deletion(-)

Index: libvirt-tck/scripts/networks/networkApplyTest.sh
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkApplyTest.sh
@@ -0,0 +1,343 @@
+#!/bin/bash
+
+VIRSH=virsh
+
+uri=
+if [ "x${LIBVIRT_TCK_CONFIG}x" != "xx" ]; then
+    uri_exp=`cat ${LIBVIRT_TCK_CONFIG} | grep "^uri\s*=" | sed -e 's/uri\s*=\s*//' | tail -n 1`
+    if [ "x${uri_exp}x" != "xx" ]; then
+        eval "uri=${uri_exp}"
+    fi
+    if [ "x${uri}x" == "xx" ]; then
+        uri="qemu:///system"
+    fi
+else
+    uri="qemu:///system"
+fi
+LIBVIRT_URI=${uri}
+
+
+FLAG_WAIT="$((1<<0))"
+FLAG_VERBOSE="$((1<<2))"
+FLAG_LIBVIRT_TEST="$((1<<3))"
+FLAG_TAP_TEST="$((1<<4))"
+FLAG_FORCE_CLEAN="$((1<<5))"
+
+failctr=0
+passctr=0
+attachfailctr=0
+attachctr=0
+
+TAP_FAIL_LIST=""
+TAP_FAIL_CTR=0
+TAP_TOT_CTR=0
+
+function usage() {
+  local cmd="$0"
+cat<<EOF
+Usage: ${cmd} [--help|-h|-?] [--noattach] [--wait] [--verbose]
+              [--libvirt-test] [--tap-test]
+
+Options:
+ --help,-h,-?   : Display this help screen.
+ --wait         : Wait for the user to press the enter key once an error
+                  was detected
+ --verbose      : Verbose output
+ --libvirt-test : Use the libvirt test output format
+ --tap-test     : TAP format output
+ --force        : Allow the automatic cleaning of VMs and networks
+                  previously created by the TCK test suite
+
+This test creates libvirt 'networks' and checks for expected results
+(iptables, running processes (dnsmasq)) using provided xml and data
+file respectively.
+EOF
+}
+
+
+function tap_fail() {
+  echo "not ok $1 - ${2:0:66}"
+  TAP_FAIL_LIST+="$1 "
+  ((TAP_FAIL_CTR++))
+  ((TAP_TOT_CTR++))
+}
+
+function tap_pass() {
+  echo "ok $1 - ${2:0:70}"
+  ((TAP_TOT_CTR++))
+}
+
+function tap_final() {
+  local okay
+
+  [ -n "${TAP_FAIL_LIST}" ]&&  echo "FAILED tests ${TAP_FAIL_LIST}"
+
+  okay=`echo "($TAP_TOT_CTR-$TAP_FAIL_CTR)*100/$TAP_TOT_CTR" | bc -l`
+  echo "Failed ${TAP_FAIL_CTR}/${TAP_TOT_CTR} tests, ${okay:0:5}% okay"
+}
+
+# A wrapper for mktemp in case it does not exist
+# Echos the name of a temporary file.
+function mktmpfile() {
+  local tmp
+  type -P mktemp>  /dev/null
+  if [ $? -eq 0 ]; then
+    tmp=$(mktemp -t nwfvmtest.XXXXXX)
+    echo ${tmp}
+  else
+    while :; do
+      tmp="/tmp/nwfvmtest.${RANDOM}"
+      if [ ! -f ${tmp} ]; then
+          touch ${tmp}
+          chmod 666 ${tmp}
+          echo ${tmp}
+          break
+      fi
+    done
+  fi
+  return 0
+}
+
+
+function checkExpectedOutput() {
+  local xmlfile="$1"
+  local datafile="$2"
+  local flags="$3"
+  local skipregex="$4"
+  local cmd line tmpfile tmpfile2 skip
+
+  tmpfile=`mktmpfile`
+  tmpfile2=`mktmpfile`
+
+  exec 4<${datafile}
+
+  read<&4
+  line="${REPLY}"
+
+  while [ "x${line}x" != "xx" ]; do
+    cmd=`echo ${line##\#}`
+
+    skip=0
+    if [ "x${skipregex}x" != "xx" ]; then
+    	skip=`echo ${cmd} | grep -c -E ${skipregex}`
+    fi
+
+    eval ${cmd} 2>&1 | tee ${tmpfile} 1>/dev/null
+
+    rm ${tmpfile2} 2>/dev/null
+    touch ${tmpfile2}
+
+    while [ 1 ]; do
+      read<&4
+      line="${REPLY}"
+
+      if [ "${line:0:1}" == "#" ] || [ "x${line}x" == "xx"  ]; then
+
+	if [ ${skip} -ne 0 ]; then
+	  break
+	fi
+
+        diff ${tmpfile} ${tmpfile2}>/dev/null
+
+        if [ $? -ne 0 ]; then
+          if [ $((flags&  FLAG_VERBOSE)) -ne 0 ]; then
+            echo "FAIL ${xmlfile} : ${cmd}"
+            diff ${tmpfile} ${tmpfile2}
+          fi
+          ((failctr++))
+          if [ $((flags&  FLAG_WAIT)) -ne 0 ]; then
+                echo "tmp files: $tmpfile, $tmpfile2"
+          	echo "Press enter"
+          	read
+          fi
+          [ $((flags&  FLAG_LIBVIRT_TEST)) -ne 0 ]&&  \
+              test_result $((passctr+failctr)) "" 1
+          [ $((flags&  FLAG_TAP_TEST)) -ne 0 ]&&  \
+             tap_fail $((passctr+failctr)) "${xmlfile} : ${cmd}"
+        else
+          ((passctr++))
+          [ $((flags&  FLAG_VERBOSE)) -ne 0 ]&&  \
+              echo "PASS ${xmlfile} : ${cmd}"
+          [ $((flags&  FLAG_LIBVIRT_TEST)) -ne 0 ]&&  \
+              test_result $((passctr+failctr)) "" 0
+          [ $((flags&  FLAG_TAP_TEST)) -ne 0 ]&&  \
+              tap_pass $((passctr+failctr)) "${xmlfile} : ${cmd}"
+        fi
+
+        break
+
+      fi
+      echo "${line}">>  ${tmpfile2}
+    done
+  done
+
+  exec 4>&-
+
+  rm -rf "${tmpfile}" "${tmpfile2}" 2>/dev/null
+}
+
+
+function doTest() {
+  local xmlfile="$1"
+  local datafile="$2"
+  local postdatafile="$3"
+  local flags="$4"
+  local netname
+
+  if [ ! -r "${xmlfile}" ]; then
+    echo "FAIL : Cannot access filter XML file ${xmlfile}."
+    return 1
+  fi
+
+  netname=`cat "${xmlfile}" | sed -n 's/.*<name>\([[:print:]]*\)<.*/\1/p'`
+
+  ${VIRSH} net-create "${xmlfile}">  /dev/null
+
+  checkExpectedOutput "${xmlfile}" "${datafile}" "${flags}" ""
+
+  ${VIRSH} net-destroy "${netname}">  /dev/null
+
+  if [ -r ${postdatafile} ]; then
+    checkExpectedOutput "${xmlfile}" "${postdatafile}" "${flags}" ""
+  fi
+
+  return 0
+}
+
+
+function runTests() {
+  local xmldir="$1"
+  local hostoutdir="$2"
+  local flags="$3"
+  local datafiles f c
+  local tap_total=0 ctr=0
+
+  pushd ${PWD}>  /dev/null
+  cd ${hostoutdir}
+  datafiles=`ls *.dat`
+  popd>  /dev/null
+
+  if [ $((flags&  FLAG_TAP_TEST)) -ne 0 ]; then
+    # Need to count the number of total tests
+    for fil in ${datafiles}; do
+      c=$(grep -c "^#" ${hostoutdir}/${fil})
+      ((tap_total+=c))
+      ((ctr++))
+    done
+    echo "1..${tap_total}"
+  fi
+
+  for fil in `echo "${datafiles}" | grep -v "\.post\.dat$"`; do
+    f=${fil%%.dat}
+    doTest "${xmldir}/${f}.xml" "${hostoutdir}/${fil}" \
+           "${hostoutdir}/${f}.post.dat" "${flags}"
+  done
+
+  if [ $((flags&  FLAG_LIBVIRT_TEST)) -ne 0 ]; then
+    test_final $((passctr+failctr)) $failctr
+  elif [ $((flags&  FLAG_TAP_TEST)) -ne 0 ]; then
+    tap_final
+  else
+    echo ""
+    echo "Summary: ${failctr} failures, ${passctr} passes,"
+    if [ ${attachctr} -ne 0 ]; then
+      echo "         ${attachfailctr} interface attachment failures with ${attachctr} attempts"
+    fi
+  fi
+}
+
+
+function main() {
+  local prgname="$0"
+  local vm1 vm2
+  local xmldir="networkxml2xmlin"
+  local hostoutdir="networkxml2hostout"
+  local res rc
+  local flags
+
+  while [ $# -ne 0 ]; do
+    case "$1" in
+    --help|-h|-\?) usage ${prgname}; exit 0;;
+    --wait)         ((flags |= FLAG_WAIT    ));;
+    --verbose)      ((flags |= FLAG_VERBOSE ));;
+    --libvirt-test) ((flags |= FLAG_LIBVIRT_TEST ));;
+    --tap-test)     ((flags |= FLAG_TAP_TEST ));;
+    --force)        ((flags |= FLAG_FORCE_CLEAN ));;
+    *) usage ${prgname}; exit 1;;
+    esac
+    shift 1
+  done
+
+  if [ `uname` != "Linux" ]; then
+    if [ $((flags&  FLAG_TAP_TEST)) -ne 0 ]; then
+      echo "1..0 # Skipped: Only valid on Linux hosts"
+    else
+      echo "This script will only run on Linux."
+    fi
+    exit 1;
+  fi
+
+  if [ $((flags&  FLAG_TAP_TEST)) -ne 0 ]; then
+    if [ "${LIBVIRT_URI}" != "qemu:///system" ]; then
+        echo "1..0 # Skipped: Only valid for Qemu system driver"
+        exit 0
+    fi
+
+    for name in `virsh list | awk '{print $2}'`
+    do
+      case ${name} in
+      tck*)
+        if [ "x${LIBVIRT_TCK_AUTOCLEAN}" == "x1" -o \
+             $((flags&  FLAG_FORCE_CLEAN)) -ne 0 ]; then
+          res=$(virsh destroy  ${name} 2>&1)
+          res=$(virsh undefine ${name} 2>&1)
+          if [ $? -ne 0 ]; then
+            echo "Bail out! Could not undefine VM ${name}: ${res}"
+            exit 0
+          fi
+        else
+          echo "Bail out! TCK VMs from previous tests still exist, use --force to clean"
+          exit 1
+        fi
+      esac
+    done
+
+    for name in `virsh net-list | sed -n '3,$p'`
+    do
+      case ${name} in
+      tck*)
+        if [ "x${LIBVIRT_TCK_AUTOCLEAN}" == "x1" -o \
+             $((flags&  FLAG_FORCE_CLEAN)) -ne 0 ]; then
+          res=$(virsh net-destroy ${name} 2>&1)
+          rc=$?
+          res=$(virsh net-undefine ${name} 2>&1)
+          if [ $rc -ne 0 -a $? -ne 0 ]; then
+            echo "Bail out! Could not destroy/undefine network ${name}: ${res}"
+            exit 1
+          fi
+        else
+          echo "Bail out! Network ${name} already exists, use --force to clean"
+          exit 1
+        fi
+      esac
+    done
+  fi
+
+  if [ $((flags&  FLAG_LIBVIRT_TEST)) -ne 0 ]; then
+    pushd ${PWD}>  /dev/null
+    . test-lib.sh
+    if [ $? -ne 0 ]; then
+        exit 1
+    fi
+    test_intro $this_test
+    popd>  /dev/null
+  fi
+
+  res=$(${VIRSH} capabilities 2>&1)
+
+  runTests "${xmldir}" "${hostoutdir}" "${flags}"
+
+  return 0
+}
+
+main "$@"
Index: libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-1.dat
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-1.dat
@@ -0,0 +1,17 @@
+#iptables -t nat -L -n | grep 10.1.2
+MASQUERADE  tcp  --  10.1.2.0/24         !10.1.2.0/24         masq ports: 1024-65535
+MASQUERADE  udp  --  10.1.2.0/24         !10.1.2.0/24         masq ports: 1024-65535
+MASQUERADE  all  --  10.1.2.0/24         !10.1.2.0/24
+#iptables -n -L FORWARD | grep 10.1.2
+ACCEPT     all  --  0.0.0.0/0            10.1.2.0/24         state RELATED,ESTABLISHED
+ACCEPT     all  --  10.1.2.0/24          0.0.0.0/0
+#ps aux | grep dnsmasq  | grep 10.1.2 | sed -n 's/.*\\(dnsmasq[[:print:]*]\\)/\\1/p'
+dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/tck-testnet.pid --conf-file=  --listen-address 10.1.2.1 --except-interface lo --dhcp-range 10.1.2.2,10.1.2.254 --dhcp-lease-max=253 --dhcp-no-override
+#route -n | grep 10.1.2
+10.1.2.0        0.0.0.0         255.255.255.0   U     0      0        0 tck-testbr
+#brctl show | grep tck-testbr
+tck-testbr		8000.000000000000	yes		
+#ifconfig tck-testbr | grep 10.1.2
+          inet addr:10.1.2.1  Bcast:10.1.2.255  Mask:255.255.255.0
+#virsh net-list | grep tck-testnet
+tck-testnet          active     no
Index: libvirt-tck/scripts/networks/networkxml2xmlin/tck-testnet-1.xml
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2xmlin/tck-testnet-1.xml
@@ -0,0 +1,12 @@
+<network>
+<name>tck-testnet</name>
+<uuid>aadc8920-502a-4774-ac2b-cd382a204d06</uuid>
+<forward mode='nat'/>
+<bridge name='tck-testbr' stp='on' delay='0' />
+<ip address='10.1.2.1' netmask='255.255.255.0'>
+<dhcp>
+<range start='10.1.2.2' end='10.1.2.254' />
+</dhcp>
+</ip>
+</network>
+
Index: libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-2.dat
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-2.dat
@@ -0,0 +1,14 @@
+#iptables -L FORWARD -n | grep 10.1.2
+ACCEPT     all  --  0.0.0.0/0            10.1.2.0/24
+ACCEPT     all  --  10.1.2.0/24          0.0.0.0/0
+#iptables -t nat -L -n | grep 10.1.2
+#ps aux | grep dnsmasq  | grep 10.1.2 | sed -n 's/.*\\(dnsmasq[[:print:]*]\\)/\\1/p'
+dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/tck-testnet.pid --conf-file=  --listen-address 10.1.2.1 --except-interface lo --dhcp-range 10.1.2.2,10.1.2.254 --dhcp-lease-max=253 --dhcp-no-override
+#route -n | grep 10.1.2
+10.1.2.0        0.0.0.0         255.255.255.0   U     0      0        0 tck-testbr
+#brctl show | grep tck-testbr
+tck-testbr		8000.000000000000	yes		
+#ifconfig tck-testbr | grep 10.1.2
+          inet addr:10.1.2.1  Bcast:10.1.2.255  Mask:255.255.255.0
+#virsh net-list | grep tck-testnet
+tck-testnet          active     no
Index: libvirt-tck/scripts/networks/networkxml2xmlin/tck-testnet-2.xml
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2xmlin/tck-testnet-2.xml
@@ -0,0 +1,12 @@
+<network>
+<name>tck-testnet</name>
+<uuid>aadc8920-502a-4774-ac2b-cd382a204d06</uuid>
+<forward mode='route'/>
+<bridge name='tck-testbr' stp='on' delay='0' />
+<ip address='10.1.2.1' netmask='255.255.255.0'>
+<dhcp>
+<range start='10.1.2.2' end='10.1.2.254' />
+</dhcp>
+</ip>
+</network>
+
Index: libvirt-tck/scripts/networks/100-apply-verify-host.t
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/100-apply-verify-host.t
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+pwd=$(dirname $0)
+
+pushd ${PWD}>  /dev/null
+
+cd ${pwd}
+bash ./networkApplyTest.sh --tap-test
+
+popd>  /dev/null
Index: libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-1.post.dat
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-1.post.dat
@@ -0,0 +1,7 @@
+#iptables -t nat -L -n | grep 10.1.2
+#iptables -n -L FORWARD | grep 10.1.2
+#ps aux | grep dnsmasq  | grep 10.1.2 | sed -n 's/.*\\(dnsmasq[[:print:]*]\\)/\\1/p'
+#route -n | grep 10.1.2
+#brctl show | grep tck-testbr
+#ifconfig tck-testbr 2>/dev/null| grep 10.1.2
+#virsh net-list | grep tck-testnet
Index: libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-2.post.dat
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-2.post.dat
@@ -0,0 +1,7 @@
+#iptables -t nat -L -n | grep 10.1.2
+#iptables -n -L FORWARD | grep 10.1.2
+#ps aux | grep dnsmasq  | grep 10.1.2 | sed -n 's/.*\\(dnsmasq[[:print:]*]\\)/\\1/p'
+#route -n | grep 10.1.2
+#brctl show | grep tck-testbr
+#ifconfig tck-testbr 2>/dev/null | grep 10.1.2
+#virsh net-list | grep tck-testnet
Index: libvirt-tck/Build.PL
===================================================================
--- libvirt-tck.orig/Build.PL
+++ libvirt-tck/Build.PL
@@ -29,7 +29,7 @@ sub process_pkgdata_files {
          my $name = $File::Find::name;
  	if (-d) {
  	    $tck_dirs{$name} = [];
-	} elsif (-f&&  (/\.t$/ || /\.sh$/ || /\.fwall$/ || /\.xml$/)) {
+	} elsif (-f&&  /\.(t|sh|fwall|xml|dat)$/) {
  	    push @{$tck_dirs{$dir}}, $name;
  	}
      };




More information about the libvir-list mailing list