+++ /dev/null
-#!/bin/bash
-
-set -e
-
-if [ -x ./xl ] ; then
- export LD_LIBRARY_PATH=.:../libxc:../xenstore
- XL=./xl
-else
- XL=xl
-fi
-
-fprefix=tmp.check-xl-disk-parse
-
-expected () {
- cat >$fprefix.expected
-}
-
-failures=0
-
-one () {
- expected_rc=$1; shift
- printf "test case %s...\n" "$*"
- set +e
- ${XL} -N block-attach 0 "$@" </dev/null >$fprefix.actual 2>/dev/null
- actual_rc=$?
- diff -u $fprefix.expected $fprefix.actual
- diff_rc=$?
- set -e
- if [ $actual_rc != $expected_rc ] || [ $diff_rc != 0 ]; then
- echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
- failures=$(( $failures + 1 ))
- fi
-}
-
-complete () {
- if [ "$failures" = 0 ]; then
- echo all ok.; exit 0
- else
- echo "$failures tests failed."; exit 1
- fi
-}
-
-e=1
-
-
-#---------- test data ----------
-#
-# culled from docs/misc/xl-disk-configuration.txt
-
-expected </dev/null
-one $e foo
-
-expected <<END
-disk: {
- "pdev_path": "/dev/vg/guest-volume",
- "vdev": "hda",
- "format": "raw",
- "readwrite": 1
-}
-
-END
-one 0 /dev/vg/guest-volume,,hda
-one 0 /dev/vg/guest-volume,raw,hda,rw
-one 0 "format=raw, vdev=hda, access=rw, target=/dev/vg/guest-volume"
-one 0 format=raw vdev=hda access=rw target=/dev/vg/guest-volume
-one 0 raw:/dev/vg/guest-volume,hda,w
-
-expected <<END
-disk: {
- "pdev_path": "/root/image.iso",
- "vdev": "hdc",
- "format": "raw",
- "removable": 1,
- "is_cdrom": 1
-}
-
-END
-one 0 /root/image.iso,,hdc,cdrom
-one 0 /root/image.iso,,hdc,,cdrom
-one 0 /root/image.iso,raw,hdc,devtype=cdrom
-one 0 "format=raw, vdev=hdc, access=ro, devtype=cdrom, target=/root/image.iso"
-one 0 format=raw vdev=hdc access=ro devtype=cdrom target=/root/image.iso
-one 0 raw:/root/image.iso,hdc:cdrom,ro
-
-expected <<EOF
-disk: {
- "pdev_path": "/dev/vg/guest-volume",
- "vdev": "xvdb",
- "backend": "phy",
- "format": "raw",
- "readwrite": 1
-}
-
-EOF
-one 0 backendtype=phy,vdev=xvdb,access=w,target=/dev/vg/guest-volume
-
-expected <<EOF
-disk: {
- "pdev_path": "",
- "vdev": "hdc",
- "format": "empty",
- "removable": 1,
- "is_cdrom": 1
-}
-
-EOF
-one 0 devtype=cdrom,,,hdc
-one 0 ,,hdc:cdrom,r
-one 0 ,hdc:cdrom,r
-one 0 vdev=hdc,access=r,devtype=cdrom,target=
-one 0 ,empty,hdc:cdrom,r
-
-expected <<EOF
-disk: {
- "vdev": "hdc",
- "format": "empty",
- "removable": 1,
- "is_cdrom": 1
-}
-
-EOF
-one 0 vdev=hdc,access=r,devtype=cdrom,format=empty
-one 0 vdev=hdc,access=r,devtype=cdrom
-
-expected <<EOF
-disk: {
- "pdev_path": "iqn.2001-05.com.equallogic:0-8a0906-23fe93404-c82797962054a96d-examplehost",
- "vdev": "xvda",
- "format": "raw",
- "script": "block-iscsi",
- "readwrite": 1
-}
-
-EOF
-
-# http://backdrift.org/xen-block-iscsi-script-with-multipath-support
-one 0 iscsi:iqn.2001-05.com.equallogic:0-8a0906-23fe93404-c82797962054a96d-examplehost,xvda,w
-one 0 vdev=xvda,access=w,script=block-iscsi,target=iqn.2001-05.com.equallogic:0-8a0906-23fe93404-c82797962054a96d-examplehost
-
-expected <<EOF
-disk: {
- "pdev_path": "app01",
- "vdev": "hda",
- "format": "raw",
- "script": "block-drbd",
- "readwrite": 1
-}
-
-EOF
-
-# http://lists.linbit.com/pipermail/drbd-user/2008-September/010221.html
-# http://www.drbd.org/users-guide-emb/s-xen-configure-domu.html
-one 0 drbd:app01,hda,w
-
-expected <<END
-disk: {
- "pdev_path": "/some/disk/image.raw",
- "vdev": "hda",
- "format": "raw",
- "readwrite": 1,
- "discard_enable": "True"
-}
-
-END
-one 0 discard vdev=hda target=/some/disk/image.raw
-one 0 discard vdev=hda target=/some/disk/image.raw
-
-expected <<END
-disk: {
- "pdev_path": "/some/disk/image.iso",
- "vdev": "hda",
- "format": "raw",
- "removable": 1,
- "is_cdrom": 1,
- "discard_enable": "False"
-}
-
-END
-one 0 cdrom no-discard vdev=hda target=/some/disk/image.iso
-
-complete
+++ /dev/null
-#!/bin/bash
-
-set -e
-
-if [ -x ./xl ] ; then
- export LD_LIBRARY_PATH=.:../libxc:../xenstore:
- XL=./xl
-else
- XL=xl
-fi
-
-fprefix=tmp.check-xl-vcpupin-parse
-outfile=check-xl-vcpupin-parse.data
-
-usage () {
-cat <<END
-usage: $0 [options]
-
-Tests various vcpu-pinning strings. If run without arguments acts
-as follows:
- - generates some test data and saves them in $outfile;
- - tests all the generated configurations (reading them back from
- $outfile).
-
-An example of a test vector file is provided in ${outfile}-example.
-
-Options:
- -h prints this message
- -r seed uses seed for initializing the rundom number generator
- (default: the script PID)
- -s string tries using string as a vcpu pinning configuration and
- reports whether that succeeds or not
- -o ofile save the test data in ofile (default: $outfile)
- -i ifile read test data from ifile
-END
-}
-
-expected () {
- cat >$fprefix.expected
-}
-
-# by default, re-seed with our PID
-seed=$$
-failures=0
-
-# Execute one test and check the result against the provided
-# rc value and output
-one () {
- expected_rc=$1; shift
- printf "test case %s...\n" "$*"
- set +e
- ${XL} -N vcpu-pin 0 all "$@" </dev/null >$fprefix.actual 2>/dev/null
- actual_rc=$?
- if [ $actual_rc != $expected_rc ]; then
- diff -u $fprefix.expected $fprefix.actual
- echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
- failures=$(( $failures + 1 ))
- fi
- set -e
-}
-
-# Write an entry in the test vector file. Format is as follows:
-# test-string*expected-rc*expected-output
-write () {
- printf "$1*$2*$3\n" >> $outfile
-}
-
-complete () {
- if [ "$failures" = 0 ]; then
- echo all ok.; exit 0
- else
- echo "$failures tests failed."; exit 1
- fi
-}
-
-# Test a specific pinning string
-string () {
- expected_rc=$1; shift
- printf "test case %s...\n" "$*"
- set +e
- ${XL} -N vcpu-pin 0 all "$@" &> /dev/null
- actual_rc=$?
- set -e
-
- if [ $actual_rc != $expected_rc ]; then
- echo >&2 "test case \`$*' failed ($actual_rc)"
- else
- echo >&2 "test case \`$*' succeeded"
- fi
-
- exit 0
-}
-
-# Read a test vector file (provided as $1) line by line and
-# test all the entries it contains
-run ()
-{
- while read line
- do
- if [ ${line:0:1} != '#' ]; then
- test_string="`echo $line | cut -f1 -d'*'`"
- exp_rc="`echo $line | cut -f2 -d'*'`"
- exp_output="`echo $line | cut -f3 -d'*'`"
-
- expected <<END
-$exp_output
-END
- one $exp_rc "$test_string"
- fi
- done < $1
-
- complete
-
- exit 0
-}
-
-while getopts "hr:s:o:i:" option
-do
- case $option in
- h)
- usage
- exit 0
- ;;
- r)
- seed=$OPTARG
- ;;
- s)
- string 0 "$OPTARG"
- ;;
- o)
- outfile=$OPTARG
- ;;
- i)
- run $OPTARG
- ;;
- esac
-done
-
-#---------- test data ----------
-#
-nr_cpus=`xl info | grep nr_cpus | cut -f2 -d':'`
-nr_nodes=`xl info | grep nr_nodes | cut -f2 -d':'`
-nr_cpus_per_node=`xl info -n | sed '/cpu:/,/numa_info/!d' | head -n -1 | \
- awk '{print $4}' | uniq -c | tail -1 | awk '{print $1}'`
-cat >$outfile <<END
-# WARNING: some of these tests are topology based tests.
-# Expect failures if the topology is not detected correctly
-# detected topology: $nr_cpus CPUs, $nr_nodes nodes, $nr_cpus_per_node CPUs per node.
-#
-# seed used for random number generation: seed=${seed}.
-#
-# Format is as follows:
-# test-string*expected-return-code*expected-output
-#
-END
-
-# Re-seed the random number generator
-RANDOM=$seed
-
-echo "# Testing a wrong configuration" >> $outfile
-write foo 255 ""
-
-echo "# Testing the 'all' syntax" >> $outfile
-write "all" 0 "cpumap: all"
-write "nodes:all" 0 "cpumap: all"
-write "all,nodes:all" 0 "cpumap: all"
-write "all,^nodes:0,all" 0 "cpumap: all"
-
-echo "# Testing the empty cpumap case" >> $outfile
-write "^0" 0 "cpumap: none"
-
-echo "# A few attempts of pinning to just one random cpu" >> $outfile
-if [ $nr_cpus -gt 1 ]; then
- for i in `seq 0 3`; do
- cpu=$(($RANDOM % nr_cpus))
- write "$cpu" 0 "cpumap: $cpu"
- done
-fi
-
-echo "# A few attempts of pinning to all but one random cpu" >> $outfile
-if [ $nr_cpus -gt 2 ]; then
- for i in `seq 0 3`; do
- cpu=$(($RANDOM % nr_cpus))
- if [ $cpu -eq 0 ]; then
- expected_range="1-$((nr_cpus - 1))"
- elif [ $cpu -eq 1 ]; then
- expected_range="0,2-$((nr_cpus - 1))"
- elif [ $cpu -eq $((nr_cpus - 2)) ]; then
- expected_range="0-$((cpu - 1)),$((nr_cpus - 1))"
- elif [ $cpu -eq $((nr_cpus - 1)) ]; then
- expected_range="0-$((nr_cpus - 2))"
- else
- expected_range="0-$((cpu - 1)),$((cpu + 1))-$((nr_cpus - 1))"
- fi
- write "all,^$cpu" 0 "cpumap: $expected_range"
- done
-fi
-
-echo "# A few attempts of pinning to a random range of cpus" >> $outfile
-if [ $nr_cpus -gt 2 ]; then
- for i in `seq 0 3`; do
- cpua=$(($RANDOM % nr_cpus))
- range=$((nr_cpus - cpua))
- cpub=$(($RANDOM % range))
- cpubb=$((cpua + cpub))
- if [ $cpua -eq $cpubb ]; then
- expected_range="$cpua"
- else
- expected_range="$cpua-$cpubb"
- fi
- write "$expected_range" 0 "cpumap: $expected_range"
- done
-fi
-
-echo "# A few attempts of pinning to just one random node" >> $outfile
-if [ $nr_nodes -gt 1 ]; then
- for i in `seq 0 3`; do
- node=$(($RANDOM % nr_nodes))
- # this assumes that the first $nr_cpus_per_node (from cpu
- # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
- # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
- # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
- # 1), etc. Expect failures if that is not the case.
- write "nodes:$node" 0 "cpumap: $((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1)-1))"
- done
-fi
-
-echo "# A few attempts of pinning to all but one random node" >> $outfile
-if [ $nr_nodes -gt 1 ]; then
- for i in `seq 0 3`; do
- node=$(($RANDOM % nr_nodes))
- # this assumes that the first $nr_cpus_per_node (from cpu
- # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
- # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
- # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
- # 1), etc. Expect failures if that is not the case.
- if [ $node -eq 0 ]; then
- expected_range="$nr_cpus_per_node-$((nr_cpus - 1))"
- elif [ $node -eq $((nr_nodes - 1)) ]; then
- expected_range="0-$((nr_cpus - nr_cpus_per_node - 1))"
- else
- expected_range="0-$((nr_cpus_per_node*node-1)),$((nr_cpus_per_node*(node+1)))-$nr_cpus"
- fi
- write "all,^nodes:$node" 0 "cpumap: $expected_range"
- done
-fi
-
-echo "# A few attempts of pinning to a random range of nodes" >> $outfile
-if [ $nr_nodes -gt 1 ]; then
- for i in `seq 0 3`; do
- nodea=$(($RANDOM % nr_nodes))
- range=$((nr_nodes - nodea))
- nodeb=$(($RANDOM % range))
- nodebb=$((nodea + nodeb))
- # this assumes that the first $nr_cpus_per_node (from cpu
- # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
- # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
- # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
- # 1), etc. Expect failures if that is not the case.
- if [ $nodea -eq 0 ] && [ $nodebb -eq $((nr_nodes - 1)) ]; then
- expected_range="all"
- else
- expected_range="$((nr_cpus_per_node*nodea))-$((nr_cpus_per_node*(nodebb+1) - 1))"
- fi
- write "nodes:$nodea-$nodebb" 0 "cpumap: $expected_range"
- done
-fi
-
-echo "# A few attempts of pinning to a node but excluding one random cpu" >> $outfile
-if [ $nr_nodes -gt 1 ]; then
- for i in `seq 0 3`; do
- node=$(($RANDOM % nr_nodes))
- # this assumes that the first $nr_cpus_per_node (from cpu
- # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
- # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
- # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
- # 1), etc. Expect failures if that is not the case.
- cpu=$(($RANDOM % nr_cpus_per_node + nr_cpus_per_node*node))
- if [ $cpu -eq $((nr_cpus_per_node*node)) ]; then
- expected_range="$((nr_cpus_per_node*node + 1))-$((nr_cpus_per_node*(node+1) - 1))"
- elif [ $cpu -eq $((nr_cpus_per_node*node + 1)) ]; then
- expected_range="$((nr_cpus_per_node*node)),$((nr_cpus_per_node*node + 2))-$((nr_cpus_per_node*(node+1) - 1))"
- elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 2)) ]; then
- expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 3)),$((nr_cpus_per_node*(node+1) - 1))"
- elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 1)) ]; then
- expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 2))"
- else
- expected_range="$((nr_cpus_per_node*node))-$((cpu - 1)),$((cpu + 1))-$((nr_cpus_per_node*(node+1) - 1))"
- fi
- write "nodes:$node,^$cpu" 0 "cpumap: $expected_range"
- done
-fi
-
-run $outfile
+++ /dev/null
-# WARNING: some of these tests are topology based tests.
-# Expect failures if the topology is not detected correctly
-# detected topology: 16 CPUs, 2 nodes, 8 CPUs per node.
-#
-# seed used for random number generation: seed=13328.
-#
-# Format is as follows:
-# test-string*expected-return-code*expected-output
-#
-# Testing a wrong configuration
-foo*255*
-# Testing the 'all' syntax
-all*0*cpumap: all
-nodes:all*0*cpumap: all
-all,nodes:all*0*cpumap: all
-all,^nodes:0,all*0*cpumap: all
-# Testing the empty cpumap case
-^0*0*cpumap: none
-# A few attempts of pinning to just one random cpu
-0*0*cpumap: 0
-9*0*cpumap: 9
-6*0*cpumap: 6
-0*0*cpumap: 0
-# A few attempts of pinning to all but one random cpu
-all,^12*0*cpumap: 0-11,13-15
-all,^6*0*cpumap: 0-5,7-15
-all,^3*0*cpumap: 0-2,4-15
-all,^7*0*cpumap: 0-6,8-15
-# A few attempts of pinning to a random range of cpus
-13-15*0*cpumap: 13-15
-7*0*cpumap: 7
-3-5*0*cpumap: 3-5
-8-11*0*cpumap: 8-11
-# A few attempts of pinning to just one random node
-nodes:1*0*cpumap: 8-15
-nodes:0*0*cpumap: 0-7
-nodes:0*0*cpumap: 0-7
-nodes:0*0*cpumap: 0-7
-# A few attempts of pinning to all but one random node
-all,^nodes:0*0*cpumap: 8-15
-all,^nodes:1*0*cpumap: 0-7
-all,^nodes:1*0*cpumap: 0-7
-all,^nodes:0*0*cpumap: 8-15
-# A few attempts of pinning to a random range of nodes
-nodes:1-1*0*cpumap: 8-15
-nodes:1-1*0*cpumap: 8-15
-nodes:0-1*0*cpumap: all
-nodes:0-0*0*cpumap: 0-7
-# A few attempts of pinning to a node but excluding one random cpu
-nodes:1,^8*0*cpumap: 9-15
-nodes:0,^6*0*cpumap: 0-5,7
-nodes:1,^9*0*cpumap: 8,10-15
-nodes:0,^5*0*cpumap: 0-4,6-7
+++ /dev/null
-#!/bin/bash
-
-set -e
-
-if [ -x ./xl ] ; then
- export LD_LIBRARY_PATH=.
- XL=./xl
-else
- XL=xl
-fi
-
-fprefix=tmp.check-xl-vif-parse
-
-expected () {
- cat >$fprefix.expected
-}
-
-failures=0
-
-one () {
- expected_rc=$1; shift
- printf "test case %s...\n" "$*"
- set +e
- ${XL} -N network-attach 0 "$@" </dev/null >$fprefix.actual 2>/dev/null
- actual_rc=$?
- diff -u $fprefix.expected $fprefix.actual
- diff_rc=$?
- set -e
- if [ $actual_rc != $expected_rc ] || [ $diff_rc != 0 ]; then
- echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
- failures=$(( $failures + 1 ))
- fi
-}
-
-complete () {
- if [ "$failures" = 0 ]; then
- echo all ok.; exit 0
- else
- echo "$failures tests failed."; exit 1
- fi
-}
-
-e=255
-
-
-#---------- test data ----------
-
-# test invalid vif config
-expected </dev/null
-one 1 foo
-
-# test invalid rate units
-expected </dev/null
-one $e rate=foo
-one $e rate=foo
-one $e rate=10MB
-one $e rate=10MB/m
-one $e rate=10ZB
-one $e rate=10ZB/s
-one $e rate=10ZB/m
-
-# test b/s and B/s rate units
-expected <<END
-vif: {
- "backend_domid": 0,
- "devid": 0,
- "mtu": 0,
- "model": null,
- "mac": "00:00:00:00:00:00",
- "ip": null,
- "bridge": null,
- "ifname": null,
- "script": null,
- "nictype": null,
- "rate_bytes_per_interval": 100000,
- "rate_interval_usecs": 50000
-}
-
-END
-
-one 0 rate=16000000b/s
-one 0 rate=16000000b/s@50ms
-one 0 rate=2000000B/s
-one 0 rate=2000000B/s@50ms
-
-# test Kb/s and KB/s rate units
-expected <<END
-vif: {
- "backend_domid": 0,
- "devid": 0,
- "mtu": 0,
- "model": null,
- "mac": "00:00:00:00:00:00",
- "ip": null,
- "bridge": null,
- "ifname": null,
- "script": null,
- "nictype": null,
- "rate_bytes_per_interval": 100,
- "rate_interval_usecs": 50000
-}
-
-END
-one 0 rate=16Kb/s
-one 0 rate=16Kb/s@50ms
-one 0 rate=2KB/s
-one 0 rate=2KB/s@50ms
-
-# test Mb/s and MB/s rate units
-expected <<END
-vif: {
- "backend_domid": 0,
- "devid": 0,
- "mtu": 0,
- "model": null,
- "mac": "00:00:00:00:00:00",
- "ip": null,
- "bridge": null,
- "ifname": null,
- "script": null,
- "nictype": null,
- "rate_bytes_per_interval": 100000,
- "rate_interval_usecs": 50000
-}
-
-END
-one 0 rate=16Mb/s
-one 0 rate=16Mb/s@50ms
-one 0 rate=2MB/s
-one 0 rate=2MB/s@50ms
-
-# test Gb/s and GB/s rate units
-expected <<END
-vif: {
- "backend_domid": 0,
- "devid": 0,
- "mtu": 0,
- "model": null,
- "mac": "00:00:00:00:00:00",
- "ip": null,
- "bridge": null,
- "ifname": null,
- "script": null,
- "nictype": null,
- "rate_bytes_per_interval": 50000000,
- "rate_interval_usecs": 50000
-}
-
-END
-one 0 rate=8Gb/s
-one 0 rate=8Gb/s@50ms
-one 0 rate=1GB/s
-one 0 rate=1GB/s@50ms
-
-# test rate overflow
-expected </dev/null
-one $e rate=4294967296b/s
-one $e rate=4294967296Kb/s
-one $e rate=4294967296Mb/s
-one $e rate=4294967296Gb/s
-
-# test rate underflow
-expected </dev/null
-one $e rate=0B/s
-
-# test invalid replenishment interval
-expected </dev/null
-one $e rate=10Mb/s@foo
-one $e rate=10Mb/s@10h
-one $e rate=10MB/s@foo
-one $e rate=10MB/s@10h
-
-# test replenishment interval in seconds
-expected <<END
-vif: {
- "backend_domid": 0,
- "devid": 0,
- "mtu": 0,
- "model": null,
- "mac": "00:00:00:00:00:00",
- "ip": null,
- "bridge": null,
- "ifname": null,
- "script": null,
- "nictype": null,
- "rate_bytes_per_interval": 10000000,
- "rate_interval_usecs": 1000000
-}
-
-END
-one 0 rate=80Mb/s@1s
-one 0 rate=10MB/s@1s
-
-# test replenishment interval overflow
-expected </dev/null
-one $e rate=1B/s@4294967296us
-one $e rate=1B/s@4294968ms
-one $e rate=1B/s@4295s
-
-# test replenishment interval underflow
-expected </dev/null
-one $e rate=1B/s@0us
-
-# test rate limiting resulting in overflow
-expected </dev/null
-one $e rate=4294967295GB/s@5us
-one $e rate=4296MB/s@4294s
-
-# test include of single '@'
-expected </dev/null
-one $e rate=@
-
-complete
--- /dev/null
+#!/bin/bash
+
+set -e
+
+if [ -x ./xl ] ; then
+ export LD_LIBRARY_PATH=.:../libxc:../xenstore
+ XL=./xl
+else
+ XL=xl
+fi
+
+fprefix=tmp.check-xl-disk-parse
+
+expected () {
+ cat >$fprefix.expected
+}
+
+failures=0
+
+one () {
+ expected_rc=$1; shift
+ printf "test case %s...\n" "$*"
+ set +e
+ ${XL} -N block-attach 0 "$@" </dev/null >$fprefix.actual 2>/dev/null
+ actual_rc=$?
+ diff -u $fprefix.expected $fprefix.actual
+ diff_rc=$?
+ set -e
+ if [ $actual_rc != $expected_rc ] || [ $diff_rc != 0 ]; then
+ echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
+ failures=$(( $failures + 1 ))
+ fi
+}
+
+complete () {
+ if [ "$failures" = 0 ]; then
+ echo all ok.; exit 0
+ else
+ echo "$failures tests failed."; exit 1
+ fi
+}
+
+e=1
+
+
+#---------- test data ----------
+#
+# culled from docs/misc/xl-disk-configuration.txt
+
+expected </dev/null
+one $e foo
+
+expected <<END
+disk: {
+ "pdev_path": "/dev/vg/guest-volume",
+ "vdev": "hda",
+ "format": "raw",
+ "readwrite": 1
+}
+
+END
+one 0 /dev/vg/guest-volume,,hda
+one 0 /dev/vg/guest-volume,raw,hda,rw
+one 0 "format=raw, vdev=hda, access=rw, target=/dev/vg/guest-volume"
+one 0 format=raw vdev=hda access=rw target=/dev/vg/guest-volume
+one 0 raw:/dev/vg/guest-volume,hda,w
+
+expected <<END
+disk: {
+ "pdev_path": "/root/image.iso",
+ "vdev": "hdc",
+ "format": "raw",
+ "removable": 1,
+ "is_cdrom": 1
+}
+
+END
+one 0 /root/image.iso,,hdc,cdrom
+one 0 /root/image.iso,,hdc,,cdrom
+one 0 /root/image.iso,raw,hdc,devtype=cdrom
+one 0 "format=raw, vdev=hdc, access=ro, devtype=cdrom, target=/root/image.iso"
+one 0 format=raw vdev=hdc access=ro devtype=cdrom target=/root/image.iso
+one 0 raw:/root/image.iso,hdc:cdrom,ro
+
+expected <<EOF
+disk: {
+ "pdev_path": "/dev/vg/guest-volume",
+ "vdev": "xvdb",
+ "backend": "phy",
+ "format": "raw",
+ "readwrite": 1
+}
+
+EOF
+one 0 backendtype=phy,vdev=xvdb,access=w,target=/dev/vg/guest-volume
+
+expected <<EOF
+disk: {
+ "pdev_path": "",
+ "vdev": "hdc",
+ "format": "empty",
+ "removable": 1,
+ "is_cdrom": 1
+}
+
+EOF
+one 0 devtype=cdrom,,,hdc
+one 0 ,,hdc:cdrom,r
+one 0 ,hdc:cdrom,r
+one 0 vdev=hdc,access=r,devtype=cdrom,target=
+one 0 ,empty,hdc:cdrom,r
+
+expected <<EOF
+disk: {
+ "vdev": "hdc",
+ "format": "empty",
+ "removable": 1,
+ "is_cdrom": 1
+}
+
+EOF
+one 0 vdev=hdc,access=r,devtype=cdrom,format=empty
+one 0 vdev=hdc,access=r,devtype=cdrom
+
+expected <<EOF
+disk: {
+ "pdev_path": "iqn.2001-05.com.equallogic:0-8a0906-23fe93404-c82797962054a96d-examplehost",
+ "vdev": "xvda",
+ "format": "raw",
+ "script": "block-iscsi",
+ "readwrite": 1
+}
+
+EOF
+
+# http://backdrift.org/xen-block-iscsi-script-with-multipath-support
+one 0 iscsi:iqn.2001-05.com.equallogic:0-8a0906-23fe93404-c82797962054a96d-examplehost,xvda,w
+one 0 vdev=xvda,access=w,script=block-iscsi,target=iqn.2001-05.com.equallogic:0-8a0906-23fe93404-c82797962054a96d-examplehost
+
+expected <<EOF
+disk: {
+ "pdev_path": "app01",
+ "vdev": "hda",
+ "format": "raw",
+ "script": "block-drbd",
+ "readwrite": 1
+}
+
+EOF
+
+# http://lists.linbit.com/pipermail/drbd-user/2008-September/010221.html
+# http://www.drbd.org/users-guide-emb/s-xen-configure-domu.html
+one 0 drbd:app01,hda,w
+
+expected <<END
+disk: {
+ "pdev_path": "/some/disk/image.raw",
+ "vdev": "hda",
+ "format": "raw",
+ "readwrite": 1,
+ "discard_enable": "True"
+}
+
+END
+one 0 discard vdev=hda target=/some/disk/image.raw
+one 0 discard vdev=hda target=/some/disk/image.raw
+
+expected <<END
+disk: {
+ "pdev_path": "/some/disk/image.iso",
+ "vdev": "hda",
+ "format": "raw",
+ "removable": 1,
+ "is_cdrom": 1,
+ "discard_enable": "False"
+}
+
+END
+one 0 cdrom no-discard vdev=hda target=/some/disk/image.iso
+
+complete
--- /dev/null
+#!/bin/bash
+
+set -e
+
+if [ -x ./xl ] ; then
+ export LD_LIBRARY_PATH=.:../libxc:../xenstore:
+ XL=./xl
+else
+ XL=xl
+fi
+
+fprefix=tmp.check-xl-vcpupin-parse
+outfile=check-xl-vcpupin-parse.data
+
+usage () {
+cat <<END
+usage: $0 [options]
+
+Tests various vcpu-pinning strings. If run without arguments acts
+as follows:
+ - generates some test data and saves them in $outfile;
+ - tests all the generated configurations (reading them back from
+ $outfile).
+
+An example of a test vector file is provided in ${outfile}-example.
+
+Options:
+ -h prints this message
+ -r seed uses seed for initializing the rundom number generator
+ (default: the script PID)
+ -s string tries using string as a vcpu pinning configuration and
+ reports whether that succeeds or not
+ -o ofile save the test data in ofile (default: $outfile)
+ -i ifile read test data from ifile
+END
+}
+
+expected () {
+ cat >$fprefix.expected
+}
+
+# by default, re-seed with our PID
+seed=$$
+failures=0
+
+# Execute one test and check the result against the provided
+# rc value and output
+one () {
+ expected_rc=$1; shift
+ printf "test case %s...\n" "$*"
+ set +e
+ ${XL} -N vcpu-pin 0 all "$@" </dev/null >$fprefix.actual 2>/dev/null
+ actual_rc=$?
+ if [ $actual_rc != $expected_rc ]; then
+ diff -u $fprefix.expected $fprefix.actual
+ echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
+ failures=$(( $failures + 1 ))
+ fi
+ set -e
+}
+
+# Write an entry in the test vector file. Format is as follows:
+# test-string*expected-rc*expected-output
+write () {
+ printf "$1*$2*$3\n" >> $outfile
+}
+
+complete () {
+ if [ "$failures" = 0 ]; then
+ echo all ok.; exit 0
+ else
+ echo "$failures tests failed."; exit 1
+ fi
+}
+
+# Test a specific pinning string
+string () {
+ expected_rc=$1; shift
+ printf "test case %s...\n" "$*"
+ set +e
+ ${XL} -N vcpu-pin 0 all "$@" &> /dev/null
+ actual_rc=$?
+ set -e
+
+ if [ $actual_rc != $expected_rc ]; then
+ echo >&2 "test case \`$*' failed ($actual_rc)"
+ else
+ echo >&2 "test case \`$*' succeeded"
+ fi
+
+ exit 0
+}
+
+# Read a test vector file (provided as $1) line by line and
+# test all the entries it contains
+run ()
+{
+ while read line
+ do
+ if [ ${line:0:1} != '#' ]; then
+ test_string="`echo $line | cut -f1 -d'*'`"
+ exp_rc="`echo $line | cut -f2 -d'*'`"
+ exp_output="`echo $line | cut -f3 -d'*'`"
+
+ expected <<END
+$exp_output
+END
+ one $exp_rc "$test_string"
+ fi
+ done < $1
+
+ complete
+
+ exit 0
+}
+
+while getopts "hr:s:o:i:" option
+do
+ case $option in
+ h)
+ usage
+ exit 0
+ ;;
+ r)
+ seed=$OPTARG
+ ;;
+ s)
+ string 0 "$OPTARG"
+ ;;
+ o)
+ outfile=$OPTARG
+ ;;
+ i)
+ run $OPTARG
+ ;;
+ esac
+done
+
+#---------- test data ----------
+#
+nr_cpus=`xl info | grep nr_cpus | cut -f2 -d':'`
+nr_nodes=`xl info | grep nr_nodes | cut -f2 -d':'`
+nr_cpus_per_node=`xl info -n | sed '/cpu:/,/numa_info/!d' | head -n -1 | \
+ awk '{print $4}' | uniq -c | tail -1 | awk '{print $1}'`
+cat >$outfile <<END
+# WARNING: some of these tests are topology based tests.
+# Expect failures if the topology is not detected correctly
+# detected topology: $nr_cpus CPUs, $nr_nodes nodes, $nr_cpus_per_node CPUs per node.
+#
+# seed used for random number generation: seed=${seed}.
+#
+# Format is as follows:
+# test-string*expected-return-code*expected-output
+#
+END
+
+# Re-seed the random number generator
+RANDOM=$seed
+
+echo "# Testing a wrong configuration" >> $outfile
+write foo 255 ""
+
+echo "# Testing the 'all' syntax" >> $outfile
+write "all" 0 "cpumap: all"
+write "nodes:all" 0 "cpumap: all"
+write "all,nodes:all" 0 "cpumap: all"
+write "all,^nodes:0,all" 0 "cpumap: all"
+
+echo "# Testing the empty cpumap case" >> $outfile
+write "^0" 0 "cpumap: none"
+
+echo "# A few attempts of pinning to just one random cpu" >> $outfile
+if [ $nr_cpus -gt 1 ]; then
+ for i in `seq 0 3`; do
+ cpu=$(($RANDOM % nr_cpus))
+ write "$cpu" 0 "cpumap: $cpu"
+ done
+fi
+
+echo "# A few attempts of pinning to all but one random cpu" >> $outfile
+if [ $nr_cpus -gt 2 ]; then
+ for i in `seq 0 3`; do
+ cpu=$(($RANDOM % nr_cpus))
+ if [ $cpu -eq 0 ]; then
+ expected_range="1-$((nr_cpus - 1))"
+ elif [ $cpu -eq 1 ]; then
+ expected_range="0,2-$((nr_cpus - 1))"
+ elif [ $cpu -eq $((nr_cpus - 2)) ]; then
+ expected_range="0-$((cpu - 1)),$((nr_cpus - 1))"
+ elif [ $cpu -eq $((nr_cpus - 1)) ]; then
+ expected_range="0-$((nr_cpus - 2))"
+ else
+ expected_range="0-$((cpu - 1)),$((cpu + 1))-$((nr_cpus - 1))"
+ fi
+ write "all,^$cpu" 0 "cpumap: $expected_range"
+ done
+fi
+
+echo "# A few attempts of pinning to a random range of cpus" >> $outfile
+if [ $nr_cpus -gt 2 ]; then
+ for i in `seq 0 3`; do
+ cpua=$(($RANDOM % nr_cpus))
+ range=$((nr_cpus - cpua))
+ cpub=$(($RANDOM % range))
+ cpubb=$((cpua + cpub))
+ if [ $cpua -eq $cpubb ]; then
+ expected_range="$cpua"
+ else
+ expected_range="$cpua-$cpubb"
+ fi
+ write "$expected_range" 0 "cpumap: $expected_range"
+ done
+fi
+
+echo "# A few attempts of pinning to just one random node" >> $outfile
+if [ $nr_nodes -gt 1 ]; then
+ for i in `seq 0 3`; do
+ node=$(($RANDOM % nr_nodes))
+ # this assumes that the first $nr_cpus_per_node (from cpu
+ # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
+ # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
+ # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
+ # 1), etc. Expect failures if that is not the case.
+ write "nodes:$node" 0 "cpumap: $((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1)-1))"
+ done
+fi
+
+echo "# A few attempts of pinning to all but one random node" >> $outfile
+if [ $nr_nodes -gt 1 ]; then
+ for i in `seq 0 3`; do
+ node=$(($RANDOM % nr_nodes))
+ # this assumes that the first $nr_cpus_per_node (from cpu
+ # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
+ # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
+ # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
+ # 1), etc. Expect failures if that is not the case.
+ if [ $node -eq 0 ]; then
+ expected_range="$nr_cpus_per_node-$((nr_cpus - 1))"
+ elif [ $node -eq $((nr_nodes - 1)) ]; then
+ expected_range="0-$((nr_cpus - nr_cpus_per_node - 1))"
+ else
+ expected_range="0-$((nr_cpus_per_node*node-1)),$((nr_cpus_per_node*(node+1)))-$nr_cpus"
+ fi
+ write "all,^nodes:$node" 0 "cpumap: $expected_range"
+ done
+fi
+
+echo "# A few attempts of pinning to a random range of nodes" >> $outfile
+if [ $nr_nodes -gt 1 ]; then
+ for i in `seq 0 3`; do
+ nodea=$(($RANDOM % nr_nodes))
+ range=$((nr_nodes - nodea))
+ nodeb=$(($RANDOM % range))
+ nodebb=$((nodea + nodeb))
+ # this assumes that the first $nr_cpus_per_node (from cpu
+ # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
+ # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
+ # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
+ # 1), etc. Expect failures if that is not the case.
+ if [ $nodea -eq 0 ] && [ $nodebb -eq $((nr_nodes - 1)) ]; then
+ expected_range="all"
+ else
+ expected_range="$((nr_cpus_per_node*nodea))-$((nr_cpus_per_node*(nodebb+1) - 1))"
+ fi
+ write "nodes:$nodea-$nodebb" 0 "cpumap: $expected_range"
+ done
+fi
+
+echo "# A few attempts of pinning to a node but excluding one random cpu" >> $outfile
+if [ $nr_nodes -gt 1 ]; then
+ for i in `seq 0 3`; do
+ node=$(($RANDOM % nr_nodes))
+ # this assumes that the first $nr_cpus_per_node (from cpu
+ # 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
+ # (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
+ # to 2*$nr_cpus_per_node-1) are assigned to the second node (node
+ # 1), etc. Expect failures if that is not the case.
+ cpu=$(($RANDOM % nr_cpus_per_node + nr_cpus_per_node*node))
+ if [ $cpu -eq $((nr_cpus_per_node*node)) ]; then
+ expected_range="$((nr_cpus_per_node*node + 1))-$((nr_cpus_per_node*(node+1) - 1))"
+ elif [ $cpu -eq $((nr_cpus_per_node*node + 1)) ]; then
+ expected_range="$((nr_cpus_per_node*node)),$((nr_cpus_per_node*node + 2))-$((nr_cpus_per_node*(node+1) - 1))"
+ elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 2)) ]; then
+ expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 3)),$((nr_cpus_per_node*(node+1) - 1))"
+ elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 1)) ]; then
+ expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 2))"
+ else
+ expected_range="$((nr_cpus_per_node*node))-$((cpu - 1)),$((cpu + 1))-$((nr_cpus_per_node*(node+1) - 1))"
+ fi
+ write "nodes:$node,^$cpu" 0 "cpumap: $expected_range"
+ done
+fi
+
+run $outfile
--- /dev/null
+# WARNING: some of these tests are topology based tests.
+# Expect failures if the topology is not detected correctly
+# detected topology: 16 CPUs, 2 nodes, 8 CPUs per node.
+#
+# seed used for random number generation: seed=13328.
+#
+# Format is as follows:
+# test-string*expected-return-code*expected-output
+#
+# Testing a wrong configuration
+foo*255*
+# Testing the 'all' syntax
+all*0*cpumap: all
+nodes:all*0*cpumap: all
+all,nodes:all*0*cpumap: all
+all,^nodes:0,all*0*cpumap: all
+# Testing the empty cpumap case
+^0*0*cpumap: none
+# A few attempts of pinning to just one random cpu
+0*0*cpumap: 0
+9*0*cpumap: 9
+6*0*cpumap: 6
+0*0*cpumap: 0
+# A few attempts of pinning to all but one random cpu
+all,^12*0*cpumap: 0-11,13-15
+all,^6*0*cpumap: 0-5,7-15
+all,^3*0*cpumap: 0-2,4-15
+all,^7*0*cpumap: 0-6,8-15
+# A few attempts of pinning to a random range of cpus
+13-15*0*cpumap: 13-15
+7*0*cpumap: 7
+3-5*0*cpumap: 3-5
+8-11*0*cpumap: 8-11
+# A few attempts of pinning to just one random node
+nodes:1*0*cpumap: 8-15
+nodes:0*0*cpumap: 0-7
+nodes:0*0*cpumap: 0-7
+nodes:0*0*cpumap: 0-7
+# A few attempts of pinning to all but one random node
+all,^nodes:0*0*cpumap: 8-15
+all,^nodes:1*0*cpumap: 0-7
+all,^nodes:1*0*cpumap: 0-7
+all,^nodes:0*0*cpumap: 8-15
+# A few attempts of pinning to a random range of nodes
+nodes:1-1*0*cpumap: 8-15
+nodes:1-1*0*cpumap: 8-15
+nodes:0-1*0*cpumap: all
+nodes:0-0*0*cpumap: 0-7
+# A few attempts of pinning to a node but excluding one random cpu
+nodes:1,^8*0*cpumap: 9-15
+nodes:0,^6*0*cpumap: 0-5,7
+nodes:1,^9*0*cpumap: 8,10-15
+nodes:0,^5*0*cpumap: 0-4,6-7
--- /dev/null
+#!/bin/bash
+
+set -e
+
+if [ -x ./xl ] ; then
+ export LD_LIBRARY_PATH=.
+ XL=./xl
+else
+ XL=xl
+fi
+
+fprefix=tmp.check-xl-vif-parse
+
+expected () {
+ cat >$fprefix.expected
+}
+
+failures=0
+
+one () {
+ expected_rc=$1; shift
+ printf "test case %s...\n" "$*"
+ set +e
+ ${XL} -N network-attach 0 "$@" </dev/null >$fprefix.actual 2>/dev/null
+ actual_rc=$?
+ diff -u $fprefix.expected $fprefix.actual
+ diff_rc=$?
+ set -e
+ if [ $actual_rc != $expected_rc ] || [ $diff_rc != 0 ]; then
+ echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
+ failures=$(( $failures + 1 ))
+ fi
+}
+
+complete () {
+ if [ "$failures" = 0 ]; then
+ echo all ok.; exit 0
+ else
+ echo "$failures tests failed."; exit 1
+ fi
+}
+
+e=255
+
+
+#---------- test data ----------
+
+# test invalid vif config
+expected </dev/null
+one 1 foo
+
+# test invalid rate units
+expected </dev/null
+one $e rate=foo
+one $e rate=foo
+one $e rate=10MB
+one $e rate=10MB/m
+one $e rate=10ZB
+one $e rate=10ZB/s
+one $e rate=10ZB/m
+
+# test b/s and B/s rate units
+expected <<END
+vif: {
+ "backend_domid": 0,
+ "devid": 0,
+ "mtu": 0,
+ "model": null,
+ "mac": "00:00:00:00:00:00",
+ "ip": null,
+ "bridge": null,
+ "ifname": null,
+ "script": null,
+ "nictype": null,
+ "rate_bytes_per_interval": 100000,
+ "rate_interval_usecs": 50000
+}
+
+END
+
+one 0 rate=16000000b/s
+one 0 rate=16000000b/s@50ms
+one 0 rate=2000000B/s
+one 0 rate=2000000B/s@50ms
+
+# test Kb/s and KB/s rate units
+expected <<END
+vif: {
+ "backend_domid": 0,
+ "devid": 0,
+ "mtu": 0,
+ "model": null,
+ "mac": "00:00:00:00:00:00",
+ "ip": null,
+ "bridge": null,
+ "ifname": null,
+ "script": null,
+ "nictype": null,
+ "rate_bytes_per_interval": 100,
+ "rate_interval_usecs": 50000
+}
+
+END
+one 0 rate=16Kb/s
+one 0 rate=16Kb/s@50ms
+one 0 rate=2KB/s
+one 0 rate=2KB/s@50ms
+
+# test Mb/s and MB/s rate units
+expected <<END
+vif: {
+ "backend_domid": 0,
+ "devid": 0,
+ "mtu": 0,
+ "model": null,
+ "mac": "00:00:00:00:00:00",
+ "ip": null,
+ "bridge": null,
+ "ifname": null,
+ "script": null,
+ "nictype": null,
+ "rate_bytes_per_interval": 100000,
+ "rate_interval_usecs": 50000
+}
+
+END
+one 0 rate=16Mb/s
+one 0 rate=16Mb/s@50ms
+one 0 rate=2MB/s
+one 0 rate=2MB/s@50ms
+
+# test Gb/s and GB/s rate units
+expected <<END
+vif: {
+ "backend_domid": 0,
+ "devid": 0,
+ "mtu": 0,
+ "model": null,
+ "mac": "00:00:00:00:00:00",
+ "ip": null,
+ "bridge": null,
+ "ifname": null,
+ "script": null,
+ "nictype": null,
+ "rate_bytes_per_interval": 50000000,
+ "rate_interval_usecs": 50000
+}
+
+END
+one 0 rate=8Gb/s
+one 0 rate=8Gb/s@50ms
+one 0 rate=1GB/s
+one 0 rate=1GB/s@50ms
+
+# test rate overflow
+expected </dev/null
+one $e rate=4294967296b/s
+one $e rate=4294967296Kb/s
+one $e rate=4294967296Mb/s
+one $e rate=4294967296Gb/s
+
+# test rate underflow
+expected </dev/null
+one $e rate=0B/s
+
+# test invalid replenishment interval
+expected </dev/null
+one $e rate=10Mb/s@foo
+one $e rate=10Mb/s@10h
+one $e rate=10MB/s@foo
+one $e rate=10MB/s@10h
+
+# test replenishment interval in seconds
+expected <<END
+vif: {
+ "backend_domid": 0,
+ "devid": 0,
+ "mtu": 0,
+ "model": null,
+ "mac": "00:00:00:00:00:00",
+ "ip": null,
+ "bridge": null,
+ "ifname": null,
+ "script": null,
+ "nictype": null,
+ "rate_bytes_per_interval": 10000000,
+ "rate_interval_usecs": 1000000
+}
+
+END
+one 0 rate=80Mb/s@1s
+one 0 rate=10MB/s@1s
+
+# test replenishment interval overflow
+expected </dev/null
+one $e rate=1B/s@4294967296us
+one $e rate=1B/s@4294968ms
+one $e rate=1B/s@4295s
+
+# test replenishment interval underflow
+expected </dev/null
+one $e rate=1B/s@0us
+
+# test rate limiting resulting in overflow
+expected </dev/null
+one $e rate=4294967295GB/s@5us
+one $e rate=4296MB/s@4294s
+
+# test include of single '@'
+expected </dev/null
+one $e rate=@
+
+complete