[Libguestfs] [PATCH v2 6/9] tests: Add tests using a captive daemon process.

Richard W.M. Jones
Thu, 25 Jun 2015 14:56:58 -0000

This allows us to test the daemon running as a host process, allowing
us to meaningfully test it using valgrind.

This commit only adds a single test that check that the daemon starts
up, can be pinged, and exits.
---
 .gitignore                        |   1 +
 Makefile.am                       |   1 +
 configure.ac                      |   2 +
 tests/daemon/Makefile.am          |  36 +++++++++++
 tests/daemon/captive-daemon.pm.in | 125 ++++++++++++++++++++++++++++++++++++++
 tests/daemon/test-daemon-start.pl |  35 +++++++++++
 6 files changed, 200 insertions(+)
 create mode 100644 tests/daemon/Makefile.am
 create mode 100644 tests/daemon/captive-daemon.pm.in
 create mode 100755 tests/daemon/test-daemon-start.pl

diff --git a/.gitignore b/.gitignore
index 6f14915..6089122 100644
--- a/.gitignore
+++ b/.gitignore
@@ -528,6 +528,7 @@ Makefile.in
 /tests/data/lib-i586.so.xz
 /tests/data/test-grep.txt.gz
 /tests/data/test.iso
+/tests/daemon/captive-daemon.pm
 /tests/disks/test-qemu-drive-libvirt.xml
 /tests/events/test-libvirt-auth-callbacks
 /tests/guests/blank-*.img
diff --git a/Makefile.am b/Makefile.am
index ad6d9d3..c545ea1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,6 +30,7 @@ SUBDIRS += tests/data generator src examples po

 if ENABLE_DAEMON
 SUBDIRS += daemon
+SUBDIRS += tests/daemon
 endif
 if ENABLE_APPLIANCE
 SUBDIRS += appliance
diff --git a/configure.ac b/configure.ac
index 8775c4b..66ac5df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1775,6 +1775,8 @@ AC_CONFIG_FILES([Makefile
                  tests/charsets/Makefile
                  tests/create/Makefile
                  tests/data/Makefile
+                 tests/daemon/Makefile
+                 tests/daemon/captive-daemon.pm
                  tests/discard/Makefile
                  tests/disks/Makefile
                  tests/disks/test-qemu-drive-libvirt.xml
diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am
new file mode 100644
index 0000000..0d2f1cd
--- /dev/null
+++ b/tests/daemon/Makefile.am
@@ -0,0 +1,36 @@
+# libguestfs
+# Copyright (C) 2015 Red Hat 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Tests in this subdirectory run the daemon as a captive host process
+# and send commands directly to it.  There is a small Perl library
+# called 'captive-daemon.pm' in this directory to help with this.
+
+include $(top_srcdir)/subdir-rules.mk
+
+check_DATA = captive-daemon.pm
+
+TESTS = \
+	test-daemon-start.pl
+
+TESTS_ENVIRONMENT = $(top_builddir)/run --test $(VG)
+
+EXTRA_DIST = \
+	captive-daemon.pm \
+	$(TESTS)
+
+check-valgrind:
+	$(MAKE) check TEST_WITH_VALGRIND=1
diff --git a/tests/daemon/captive-daemon.pm.in
b/tests/daemon/captive-daemon.pm.in
new file mode 100644
index 0000000..991a9a1
--- /dev/null
+++ b/tests/daemon/captive-daemon.pm.in
@@ -0,0 +1,125 @@
+# libguestfs
+# Copyright (C) 2015 Red Hat Inc.
+# @configure_input@
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Small library to help testing the daemon directly.
+
+package CaptiveDaemon;
+
+use strict;
+use warnings;
+
+use Sys::Guestfs;
+
+$| = 1;
+
+# Filled in by autoconf.
+my %var;
+$var{top_builddir} = "@top_builddir@";
+$var{abs_top_srcdir} = "@abs_top_srcdir@";
+$var{abs_top_builddir} = "@abs_top_builddir@";
+$var{VALGRIND} = "@VALGRIND@";
+
+# Now we have to substitute the above variables into this one:
+my $VG = '@VG@';
+$VG =~ s/\$\(([A-Za-z_]+)\)/ $var{"$1"} /ge;
+
+# Refuse to run if the user is trying to run tests as root.  There's
+# too much risk that things will go badly wrong.
+if ($> == 0) {
+    print "$0: don't run the libguestfs tests as root!\n";
+    exit 77
+}
+
+sub run_tests {
+    my $g = Sys::Guestfs->new();
+    my $tmpdir = $g->get_tmpdir;
+    my $verbose = $g->get_verbose;
+    $g->close;
+
+    # Choose a random name for the socket.  The daemon will create the
+    # socket so we don't need to do that.
+    my @chars = ("A".."Z", "a".."z",
"0".."9");
+    my $sockname = $tmpdir;
+    $sockname .= "/";
+    $sockname .= $chars[rand @chars] for 1..8;
+
+    # Assemble the command we will run in the subprocess.
+    my $cmd +        "$var{top_builddir}/daemon/guestfsd --channel
$sockname -r -t -l";
+    if ($verbose) {
+        $cmd = $cmd . " -v"
+    }
+    if ($ENV{TEST_WITH_VALGRIND}) {
+        $cmd = $VG . " " . $cmd
+    }
+
+    if ($verbose) {
+        print "$0: running: $cmd\n";
+    }
+
+    # Fork to run the daemon in the background.
+    my $pid = fork ();
+    die "fork: $!" unless defined $pid;
+    if ($pid == 0) {
+        # Child process: the daemon.
+        exec $cmd or die "guestfsd: $!";
+    }
+
+    # Wait for the daemon to create the socket, but if it doesn't
+    # appear after a short timeout, assume there has been a failure.
+    for (my $i = 0; $i < 10; ++$i) {
+        last if -S $sockname;
+        sleep 1;
+    }
+    die "subprocess did not create the socket, check earlier
messages\n"
+        unless -S $sockname;
+
+    # Create the libguestfs handle and connect to the daemon using
+    # libguestfs live.
+    $g = Sys::Guestfs->new ();
+    $g->set_backend ("unix:" . $sockname);
+    $g->launch;
+
+    # Run the user tests.
+    my $r = ::tests ($g);
+
+    # Close the socket.  The daemon should now exit.
+    $g->shutdown ();
+    $g->close ();
+    unlink $sockname;
+
+    waitpid ($pid, 0) or die "waitpid: $!";
+    if ($? != 0) {
+        my $signal = $? & 127;
+        die "ERROR: guestfsd died on signal $signal\n" if $signal;
+        my $crash = $? & 128;
+        die "ERROR: guestfsd core dumped\n" if $crash;
+        my $status = $? >> 8;
+        die "ERROR: guestfsd died with exit code 119 (valgrind
failure)\n"
+            if $status == 119;
+
+        # Note we allow guestfsd to die with exit code 1, because
+        # that indicates a read failure from the socket.
+        die "ERROR: guestfsd died with exit code $status\n" if
$status > 1;
+    }
+
+    # Exit with failure if the user test failed.
+    exit 1 unless $r
+}
+
+1;
diff --git a/tests/daemon/test-daemon-start.pl
b/tests/daemon/test-daemon-start.pl
new file mode 100755
index 0000000..91e008a
--- /dev/null
+++ b/tests/daemon/test-daemon-start.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl -w
+# libguestfs
+# Copyright (C) 2015 Red Hat 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Test that the daemon starts and stops.
+
+use strict;
+use warnings;
+
+require 'captive-daemon.pm';
+
+sub tests {
+    my $g = shift;
+
+    $g->ping_daemon;
+
+    # Return true to indicate the test succeeded.
+    1;
+}
+
+CaptiveDaemon::run_tests ()
--
2.3.1