[virt-tools-list] [PATCH libosinfo 4/4] Add a test case which validates all schemas in tree
Daniel P. Berrange
berrange at redhat.com
Thu Feb 23 17:20:02 UTC 2012
From: "Daniel P. Berrange" <berrange at redhat.com>
---
Makefile.am | 4 +-
build-aux/mktempd | 135 ++++++++++++++++++++++++++++
test/Makefile.am | 30 +++++--
test/test-lib.sh | 228 ++++++++++++++++++++++++++++++++++++++++++++++++
test/test-xml-validate | 48 ++++++++++
5 files changed, 438 insertions(+), 7 deletions(-)
create mode 100755 build-aux/mktempd
create mode 100644 test/test-lib.sh
create mode 100755 test/test-xml-validate
diff --git a/Makefile.am b/Makefile.am
index a8df435..e63f391 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,9 @@ EXTRA_DIST = \
COPYING.LIB \
libosinfo.spec \
libosinfo.spec.in \
- mingw32-libosinfo.spec.in
+ mingw32-libosinfo.spec.in \
+ build-aux/mktempd \
+ $(NULL)
DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
diff --git a/build-aux/mktempd b/build-aux/mktempd
new file mode 100755
index 0000000..ab3cf14
--- /dev/null
+++ b/build-aux/mktempd
@@ -0,0 +1,135 @@
+#!/bin/sh
+# Create a temporary directory, much like mktemp -d does.
+
+# Copyright (C) 2007-2012 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Written by Jim Meyering.
+
+# Usage: mktempd /tmp phoey.XXXXXXXXXX
+
+# First, try to use the mktemp program.
+# Failing that, we'll roll our own mktemp-like function:
+# - try to get random bytes from /dev/urandom
+# - failing that, generate output from a combination of quickly-varying
+# sources and gzip. Ignore non-varying gzip header, and extract
+# "random" bits from there.
+# - given those bits, map to file-name bytes using tr, and try to create
+# the desired directory.
+# - make only $MAX_TRIES attempts
+
+ME=`basename "$0"`
+die() { echo >&2 "$ME: $@"; exit 1; }
+
+MAX_TRIES=4
+
+rand_bytes()
+{
+ n=$1
+
+ chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
+ dev_rand=/dev/urandom
+ if test -r "$dev_rand"; then
+ # Note: 256-length($chars) == 194; 3 copies of $chars is 186 + 8 = 194.
+ dd ibs=$n count=1 if="$dev_rand" 2>/dev/null \
+ | tr -c $chars 01234567$chars$chars$chars
+ return
+ fi
+
+ cmds='date; date +%N; free; who -a; w; ps auxww; ps ef; netstat -n'
+ data=` (eval "$cmds") 2>&1 | gzip `
+
+ n_plus_50=`expr $n + 50`
+
+ # Ensure that $data has length at least 50+$n
+ while :; do
+ len=`echo "$data"|wc -c`
+ test $n_plus_50 -le $len && break;
+ data=` (echo "$data"; eval "$cmds") 2>&1 | gzip `
+ done
+
+ echo "$data" \
+ | dd bs=1 skip=50 count=$n 2>/dev/null \
+ | tr -c $chars 01234567$chars$chars$chars
+}
+
+mktempd()
+{
+ case $# in
+ 2);;
+ *) die "Usage: $ME DIR TEMPLATE";;
+ esac
+
+ destdir=$1
+ template=$2
+
+ # Disallow any trailing slash on specified destdir:
+ # it would subvert the post-mktemp "case"-based destdir test.
+ case $destdir in
+ /) ;;
+ */) die "invalid destination dir: remove trailing slash(es)";;
+ esac
+
+ case $template in
+ *XXXX) ;;
+ *) die "invalid template: $template (must have a suffix of at least 4 X's)";;
+ esac
+
+ fail=0
+
+ # First, try to use mktemp.
+ d=`env -u TMPDIR mktemp -d -t -p "$destdir" "$template" 2>/dev/null` \
+ || fail=1
+
+ # The resulting name must be in the specified directory.
+ case $d in "$destdir"*);; *) fail=1;; esac
+
+ # It must have created the directory.
+ test -d "$d" || fail=1
+
+ # It must have 0700 permissions. Handle sticky "S" bits.
+ perms=`ls -dgo "$d" 2>/dev/null|tr S -` || fail=1
+ case $perms in drwx------*) ;; *) fail=1;; esac
+
+ test $fail = 0 && {
+ echo "$d"
+ return
+ }
+
+ # If we reach this point, we'll have to create a directory manually.
+
+ # Get a copy of the template without its suffix of X's.
+ base_template=`echo "$template"|sed 's/XX*$//'`
+
+ # Calculate how many X's we've just removed.
+ template_length=`echo "$template" | wc -c`
+ nx=`echo "$base_template" | wc -c`
+ nx=`expr $template_length - $nx`
+
+ err=
+ i=1
+ while :; do
+ X=`rand_bytes $nx`
+ candidate_dir="$destdir/$base_template$X"
+ err=`mkdir -m 0700 "$candidate_dir" 2>&1` \
+ && { echo "$candidate_dir"; return; }
+ test $MAX_TRIES -le $i && break;
+ i=`expr $i + 1`
+ done
+ die "$err"
+}
+
+mktempd "$@"
diff --git a/test/Makefile.am b/test/Makefile.am
index 94543ef..83ecd7d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -101,12 +101,30 @@ test_treeuris_LDADD = $(COMMON_LDADD)
test_treeuris_CFLAGS = $(COMMON_CFLAGS)
test_treeuris_SOURCES = test-treeuris.c
-TESTS = $(check_PROGRAMS)
-
-TESTS_ENVIRONMENT = \
- LC_ALL=C \
- G_SLICE=always-malloc G_DEBUG=gc-friendly \
+TEST_SCRIPT_FILES = \
+ test-xml-validate
+
+TESTS = $(check_PROGRAMS) \
+ $(TEST_SCRIPT_FILES)
+ $(NULL)
+
+EXTRA_DIST += \
+ $(TEST_SCRIPT_FILES) \
+ test-lib.sh \
+ $(NULL)
+
+TESTS_ENVIRONMENT = \
+ abs_top_builddir=$(lv_abs_top_builddir) \
+ abs_top_srcdir=`cd '$(top_srcdir)'; pwd` \
+ abs_builddir=`pwd` \
+ abs_srcdir=`cd '$(srcdir)'; pwd` \
+ CONFIG_HEADER="`cd '$(top_builddir)'; pwd`/config.h" \
+ PATH="$(path_add)$(PATH_SEPARATOR)$$PATH" \
+ SHELL="$(SHELL)" \
+ LIBVIRT_DRIVER_DIR="$(abs_top_builddir)/src/.libs" \
+ LC_ALL=C \
+ G_SLICE=always-malloc G_DEBUG=gc-friendly \
$(VG)
valgrind:
- $(MAKE) check VG="libtool --mode=execute valgrind --quiet --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=20 --suppressions=osinfo.suppression"
+ $(MAKE) check VG="libtool --mode=execute valgrind --quiet --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=20 --suppressions=osinfo.suppression"
diff --git a/test/test-lib.sh b/test/test-lib.sh
new file mode 100644
index 0000000..918bf73
--- /dev/null
+++ b/test/test-lib.sh
@@ -0,0 +1,228 @@
+# source this file; set up for tests
+
+test -z "$abs_srcdir" && abs_srcdir=$(pwd)
+test -z "$abs_builddir" && abs_builddir=$(pwd)
+test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/..
+test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/..
+test -z "$LC_ALL" && LC_ALL=C
+
+# Skip this test if the shell lacks support for functions.
+unset function_test
+eval 'function_test() { return 11; }; function_test'
+if test $? != 11; then
+ echo "$0: /bin/sh lacks support for functions; skipping this test." 1>&2
+ (exit 77); exit 77
+fi
+
+test_intro()
+{
+ name=$1
+ if test "$verbose" = "0" ; then
+ echo "TEST: $name"
+ printf " "
+ fi
+}
+
+test_result()
+{
+ counter=$1
+ name=$2
+ status=$3
+ if test "$verbose" = "0" ; then
+ mod=`expr \( $counter + 40 - 1 \) % 40`
+ if test "$counter" != 1 && test "$mod" = 0 ; then
+ printf " %-3d\n" `expr $counter - 1`
+ printf " "
+ fi
+ if test "$status" = "0" ; then
+ printf "."
+ else
+ printf "!"
+ fi
+ else
+ if test "$status" = "0" ; then
+ printf "%3d) %-60s ... OK\n" "$counter" "$name"
+ else
+ printf "%3d) %-60s ... FAILED\n" "$counter" "$name"
+ fi
+ fi
+}
+
+test_final()
+{
+ counter=$1
+ status=$2
+
+ if test "$verbose" = "0" ; then
+ len=`expr 39 - \( \( $counter - 1 \) % 40 \)`
+ printf "%${len}s" ""
+ if test "$status" = "0" ; then
+ printf " %-3d OK\n" $counter
+ else
+ printf " %-3d FAILED\n" $counter
+ fi
+ fi
+}
+
+skip_test_()
+{
+ echo "$0: skipping test: $@" 1>&2
+ (exit 77); exit 77
+}
+
+require_acl_()
+{
+ getfacl --version < /dev/null > /dev/null 2>&1 \
+ && setfacl --version < /dev/null > /dev/null 2>&1 \
+ || skip_test_ "This test requires getfacl and setfacl."
+
+ id -u bin > /dev/null 2>&1 \
+ || skip_test_ "This test requires a local user named bin."
+}
+
+require_ulimit_()
+{
+ ulimit_works=yes
+ # Expect to be able to exec a program in 10MB of virtual memory,
+ # but not in 20KB. I chose "date". It must not be a shell built-in
+ # function, so you can't use echo, printf, true, etc.
+ # Of course, in coreutils, I could use $top_builddir/src/true,
+ # but this should be able to work for other projects, too.
+ ( ulimit -v 10000; date ) > /dev/null 2>&1 || ulimit_works=no
+ ( ulimit -v 20; date ) > /dev/null 2>&1 && ulimit_works=no
+
+ test $ulimit_works = no \
+ && skip_test_ "this shell lacks ulimit support"
+}
+
+require_readable_root_()
+{
+ test -r / || skip_test_ "/ is not readable"
+}
+
+# Skip the current test if strace is not available or doesn't work.
+require_strace_()
+{
+ strace -V < /dev/null > /dev/null 2>&1 ||
+ skip_test_ 'no strace program'
+
+ strace -qe unlink echo > /dev/null 2>&1 ||
+ skip_test_ 'strace does not work'
+}
+
+require_built_()
+{
+ skip_=no
+ for i in "$@"; do
+ case " $built_programs " in
+ *" $i "*) ;;
+ *) echo "$i: not built" 1>&2; skip_=yes ;;
+ esac
+ done
+
+ test $skip_ = yes && skip_test_ "required program(s) not built"
+}
+
+uid_is_privileged_()
+{
+ # Make sure id -u succeeds.
+ my_uid=$(id -u) \
+ || { echo "$0: cannot run \`id -u'" 1>&2; return 1; }
+
+ # Make sure it gives valid output.
+ case $my_uid in
+ 0) ;;
+ *[!0-9]*)
+ echo "$0: invalid output (\`$my_uid') from \`id -u'" 1>&2
+ return 1 ;;
+ *) return 1 ;;
+ esac
+}
+
+skip_if_()
+{
+ case $1 in
+ root) skip_test_ must be run as root ;;
+ non-root) skip_test_ must be run as non-root ;;
+ *) ;; # FIXME?
+ esac
+}
+
+require_selinux_()
+{
+ case `ls -Zd .` in
+ '? .'|'unlabeled .')
+ skip_test_ "this system (or maybe just" \
+ "the current file system) lacks SELinux support"
+ ;;
+ esac
+}
+
+very_expensive_()
+{
+ if test "$RUN_VERY_EXPENSIVE_TESTS" != yes; then
+ skip_test_ '
+This test is very expensive, so it is disabled by default.
+To run it anyway, rerun make check with the RUN_VERY_EXPENSIVE_TESTS
+environment variable set to yes. E.g.,
+
+ env RUN_VERY_EXPENSIVE_TESTS=yes make check
+'
+ fi
+}
+
+require_root_() { uid_is_privileged_ || skip_test_ "must be run as root"; }
+skip_if_root_() { uid_is_privileged_ && skip_test_ "must be run as non-root"; }
+error_() { echo "$0: $@" 1>&2; (exit 1); exit 1; }
+framework_failure() { error_ 'failure in testing framework'; }
+
+mkfifo_or_skip_()
+{
+ test $# = 1 || framework_failure
+ if ! mkfifo "$1"; then
+ # Make an exception of this case -- usually we interpret framework-creation
+ # failure as a test failure. However, in this case, when running on a SunOS
+ # system using a disk NFS mounted from OpenBSD, the above fails like this:
+ # mkfifo: cannot make fifo `fifo-10558': Not owner
+ skip_test_ 'NOTICE: unable to create test prerequisites'
+ fi
+}
+
+test_dir_=$(pwd)
+
+this_test_() { echo "./$0" | sed 's,.*/,,'; }
+this_test=$(this_test_)
+
+verbose=0
+if test -n "$VIR_TEST_DEBUG" || test -n "$VIR_TEST_VERBOSE" ; then
+ verbose=1
+fi
+
+# This is a stub function that is run upon trap (upon regular exit and
+# interrupt). Override it with a per-test function, e.g., to unmount
+# a partition, or to undo any other global state changes.
+cleanup_() { :; }
+
+mktempd="$abs_top_srcdir/build-aux/mktempd"
+t_=$("$SHELL" "$mktempd" "$test_dir_" lv-$this_test.XXXXXXXXXX) \
+ || error_ "failed to create temporary directory in $test_dir_"
+
+# Run each test from within a temporary sub-directory named after the
+# test itself, and arrange to remove it upon exception or normal exit.
+trap 'st=$?; cleanup_; d='"$t_"';
+ cd '"$test_dir_"' && chmod -R u+rwx "$d" && rm -rf "$d" && exit $st' 0
+trap '(exit $?); exit $?' 1 2 13 15
+
+cd "$t_" || error_ "failed to cd to $t_"
+
+if ( diff --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { diff -u "$@"; }
+elif ( cmp --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+ compare() { cmp -s "$@"; }
+else
+ compare() { cmp "$@"; }
+fi
+
+# Local Variables:
+# indent-tabs-mode: nil
+# End:
diff --git a/test/test-xml-validate b/test/test-xml-validate
new file mode 100755
index 0000000..e5be325
--- /dev/null
+++ b/test/test-xml-validate
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+check_schema () {
+
+DIRS=$1
+SCHEMA="$abs_srcdir/../data/schemas/$2"
+
+test_intro $this_test
+
+n=0
+f=0
+for dir in $DIRS
+do
+ XML=`find $abs_srcdir/../data/$dir -name '*.xml'` || exit 1
+
+ for xml in `echo "$XML" | sort`
+ do
+ n=`expr $n + 1`
+ cmd="xmllint --relaxng $SCHEMA --noout $xml"
+ result=`$cmd 2>&1`
+ ret=$?
+
+ test_result $n $(basename $(dirname $xml))"/"$(basename $xml) $ret
+ if test "$verbose" = "1" && test $ret != 0 ; then
+ printf '%s\n' "$cmd" "$result"
+ fi
+ if test "$ret" != 0 ; then
+ f=`expr $f + 1`
+ fi
+ done
+done
+
+test_final $n $f
+
+ret=0
+test $f != 0 && ret=255
+exit $ret
+
+}
+
+
+: ${srcdir=.}
+. $srcdir/test-lib.sh
+
+DIRS="oses hypervisors devices"
+SCHEMA="libosinfo.rng"
+
+check_schema "$DIRS" "$SCHEMA"
--
1.7.7.6
More information about the virt-tools-list
mailing list