Test that blkdiscard, -o discard, and fstrim work in reality, end-to-end.
---
Makefile.am | 1 +
configure.ac | 1 +
tests/discard/Makefile.am | 28 +++++++++
tests/discard/test-blkdiscard.pl | 111 ++++++++++++++++++++++++++++++++++
tests/discard/test-discard.pl | 117 ++++++++++++++++++++++++++++++++++++
tests/discard/test-fstrim.pl | 125 +++++++++++++++++++++++++++++++++++++++
6 files changed, 383 insertions(+)
create mode 100644 tests/discard/Makefile.am
create mode 100755 tests/discard/test-blkdiscard.pl
create mode 100755 tests/discard/test-discard.pl
create mode 100755 tests/discard/test-fstrim.pl
diff --git a/Makefile.am b/Makefile.am
index 020628e..11b12c2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -46,6 +46,7 @@ SUBDIRS += tests/events
SUBDIRS += tests/parallel
SUBDIRS += tests/create
SUBDIRS += tests/disks
+SUBDIRS += tests/discard
SUBDIRS += tests/mountable
SUBDIRS += tests/network
SUBDIRS += tests/lvm
diff --git a/configure.ac b/configure.ac
index 35460e2..3785ea8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1673,6 +1673,7 @@ AC_CONFIG_FILES([Makefile
tests/charsets/Makefile
tests/create/Makefile
tests/data/Makefile
+ tests/discard/Makefile
tests/disks/Makefile
tests/disks/test-qemu-drive-libvirt.xml
tests/disk-labels/Makefile
diff --git a/tests/discard/Makefile.am b/tests/discard/Makefile.am
new file mode 100644
index 0000000..e109628
--- /dev/null
+++ b/tests/discard/Makefile.am
@@ -0,0 +1,28 @@
+# libguestfs
+# Copyright (C) 2014 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.
+
+include $(top_srcdir)/subdir-rules.mk
+
+TESTS = \
+ test-blkdiscard.pl \
+ test-discard.pl \
+ test-fstrim.pl
+
+TESTS_ENVIRONMENT = $(top_builddir)/run --test
+
+EXTRA_DIST = \
+ $(TESTS)
diff --git a/tests/discard/test-blkdiscard.pl b/tests/discard/test-blkdiscard.pl
new file mode 100755
index 0000000..3caafbc
--- /dev/null
+++ b/tests/discard/test-blkdiscard.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+# Copyright (C) 2014 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 blkdiscard works.
+
+use strict;
+use warnings;
+
+use Sys::Guestfs;
+
+# Since we read error messages, we want to ensure they are printed
+# in English, hence:
+$ENV{"LANG"} = "C";
+
+$| = 1;
+
+if ($ENV{SKIP_TEST_BLKDISCARD_PL}) {
+ print "$0: skipped test because environment variable is set\n";
+ exit 77;
+}
+
+my $g = Sys::Guestfs->new ();
+
+# Discard is only supported when using qemu.
+if ($g->get_backend () ne "libvirt" &&
+ $g->get_backend () !~ /^libvirt:/ &&
+ $g->get_backend () ne "direct") {
+ print "$0: skipped test because discard is only supported when using
qemu\n";
+ exit 77;
+}
+
+# You can set this to "raw" or "qcow2".
+my $format = "raw";
+
+my $size = 5 * 1024 * 1024;
+
+my $disk;
+my @args;
+if ($format eq "raw") {
+ $disk = "test-blkdiscard.img";
+ @args = ( preallocation => "sparse" );
+} elsif ($format eq "qcow2") {
+ $disk = "test-blkdiscard.qcow2";
+ @args = ( preallocation => "off", compat => "1.1" );
+} else {
+ die "$0: invalid disk format: $format\n";
+}
+
+# Create a disk and add it with discard enabled. This is allowed to
+# fail, eg because qemu is too old, but libguestfs must tell us that
+# it failed (since we're using 'enable', not 'besteffort').
+$g->disk_create ($disk, $format, $size, @args);
+END { unlink ($disk); };
+
+eval {
+ $g->add_drive ($disk, format => $format, readonly => 0, discard =>
"enable");
+ $g->launch ();
+};
+if ($@) {
+ if ($@ =~ /discard cannot be enabled on this drive/) {
+ # This is OK. Libguestfs says it's not possible to enable
+ # discard on this drive (eg. because qemu is too old). Print
+ # the reason and skip the test.
+ print "$0: skipped test: $@\n";
+ exit 77;
+ }
+ die # propagate the unexpected error
+}
+
+# At this point we've got a disk which claims to support discard.
+# Let's test that theory.
+
+my $orig_size = (stat ($disk))[12];
+print "original size:\t$orig_size (blocks)\n";
+
+# Fill the block device with some random data.
+
+$g->copy_device_to_device ("/dev/urandom", "/dev/sda", size =>
$size);
+$g->sync ();
+
+my $full_size = (stat ($disk))[12];
+print "full size:\t$full_size (blocks)\n";
+
+die "$0: surprising result: full size <= original size\n"
+ if $full_size <= $orig_size;
+
+# Discard the data on the device.
+
+$g->blkdiscard ("/dev/sda");
+$g->shutdown ();
+$g->close ();
+
+my $trimmed_size = (stat ($disk))[12];
+print "trimmed size:\t$trimmed_size (blocks)\n";
+
+die "$0: looks like the blkdiscard operation did not work\n"
+ if $trimmed_size >= $full_size;
diff --git a/tests/discard/test-discard.pl b/tests/discard/test-discard.pl
new file mode 100755
index 0000000..3f350b3
--- /dev/null
+++ b/tests/discard/test-discard.pl
@@ -0,0 +1,117 @@
+#!/usr/bin/perl
+# Copyright (C) 2014 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 -o discard works.
+
+use strict;
+use warnings;
+
+use Sys::Guestfs;
+
+# Since we read error messages, we want to ensure they are printed
+# in English, hence:
+$ENV{"LANG"} = "C";
+
+$| = 1;
+
+if ($ENV{SKIP_TEST_DISCARD_PL}) {
+ print "$0: skipped test because environment variable is set\n";
+ exit 77;
+}
+
+my $g = Sys::Guestfs->new ();
+
+# Discard is only supported when using qemu.
+if ($g->get_backend () ne "libvirt" &&
+ $g->get_backend () !~ /^libvirt:/ &&
+ $g->get_backend () ne "direct") {
+ print "$0: skipped test because discard is only supported when using
qemu\n";
+ exit 77;
+}
+
+# You can set this to "raw" or "qcow2".
+my $format = "raw";
+
+# Size needs to be at least 32 MB so we can fit an ext4 filesystem on it.
+my $size = 64 * 1024 * 1024;
+
+my $disk;
+my @args;
+if ($format eq "raw") {
+ $disk = "test-discard.img";
+ @args = ( preallocation => "sparse" );
+} elsif ($format eq "qcow2") {
+ $disk = "test-discard.qcow2";
+ @args = ( preallocation => "off", compat => "1.1" );
+} else {
+ die "$0: invalid disk format: $format\n";
+}
+
+# Create a disk and add it with discard enabled. This is allowed to
+# fail, eg because qemu is too old, but libguestfs must tell us that
+# it failed (since we're using 'enable', not 'besteffort').
+$g->disk_create ($disk, $format, $size, @args);
+END { unlink ($disk); };
+
+eval {
+ $g->add_drive ($disk, format => $format, readonly => 0, discard =>
"enable");
+ $g->launch ();
+};
+if ($@) {
+ if ($@ =~ /discard cannot be enabled on this drive/) {
+ # This is OK. Libguestfs says it's not possible to enable
+ # discard on this drive (eg. because qemu is too old). Print
+ # the reason and skip the test.
+ print "$0: skipped test: $@\n";
+ exit 77;
+ }
+ die # propagate the unexpected error
+}
+
+# At this point we've got a disk which claims to support discard.
+# Let's test that theory.
+
+my $orig_size = (stat ($disk))[12];
+print "original size:\t$orig_size (blocks)\n";
+#system "du -sh $disk";
+
+# Write a filesystem onto the disk and fill it with data.
+
+$g->mkfs ("ext4", "/dev/sda");
+$g->mount_options ("discard", "/dev/sda", "/");
+$g->fill (33, 10000000, "/data");
+$g->sync ();
+
+my $full_size = (stat ($disk))[12];
+print "full size:\t$full_size (blocks)\n";
+#system "du -sh $disk";
+
+die "$0: surprising result: full size <= original size\n"
+ if $full_size <= $orig_size;
+
+# Remove the file and check the filesystem is trimmed automatically.
+
+$g->rm ("/data");
+$g->sync ();
+$g->close ();
+
+my $trimmed_size = (stat ($disk))[12];
+print "trimmed size:\t$trimmed_size (blocks)\n";
+#system "du -sh $disk";
+
+die "$0: looks like the -o discard mount option did not work\n"
+ if $trimmed_size >= $full_size;
diff --git a/tests/discard/test-fstrim.pl b/tests/discard/test-fstrim.pl
new file mode 100755
index 0000000..54451b8
--- /dev/null
+++ b/tests/discard/test-fstrim.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/perl
+# Copyright (C) 2014 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 fstrim works.
+
+use strict;
+use warnings;
+
+use Sys::Guestfs;
+
+# Since we read error messages, we want to ensure they are printed
+# in English, hence:
+$ENV{"LANG"} = "C";
+
+$| = 1;
+
+if ($ENV{SKIP_TEST_FSTRIM_PL}) {
+ print "$0: skipped test because environment variable is set\n";
+ exit 77;
+}
+
+my $g = Sys::Guestfs->new ();
+
+# Discard is only supported when using qemu.
+if ($g->get_backend () ne "libvirt" &&
+ $g->get_backend () !~ /^libvirt:/ &&
+ $g->get_backend () ne "direct") {
+ print "$0: skipped test because discard is only supported when using
qemu\n";
+ exit 77;
+}
+
+# You can set this to "raw" or "qcow2".
+my $format = "raw";
+
+# Size needs to be at least 32 MB so we can fit an ext4 filesystem on it.
+my $size = 64 * 1024 * 1024;
+
+my $disk;
+my @args;
+if ($format eq "raw") {
+ $disk = "test-fstrim.img";
+ @args = ( preallocation => "sparse" );
+} elsif ($format eq "qcow2") {
+ $disk = "test-fstrim.qcow2";
+ @args = ( preallocation => "off", compat => "1.1" );
+} else {
+ die "$0: invalid disk format: $format\n";
+}
+
+# Create a disk and add it with discard enabled. This is allowed to
+# fail, eg because qemu is too old, but libguestfs must tell us that
+# it failed (since we're using 'enable', not 'besteffort').
+$g->disk_create ($disk, $format, $size, @args);
+END { unlink ($disk); };
+
+eval {
+ $g->add_drive ($disk, format => $format, readonly => 0, discard =>
"enable");
+ $g->launch ();
+};
+if ($@) {
+ if ($@ =~ /discard cannot be enabled on this drive/) {
+ # This is OK. Libguestfs says it's not possible to enable
+ # discard on this drive (eg. because qemu is too old). Print
+ # the reason and skip the test.
+ print "$0: skipped test: $@\n";
+ exit 77;
+ }
+ die # propagate the unexpected error
+}
+
+# Is fstrim available in the appliance?
+unless ($g->feature_available (["fstrim"])) {
+ print "$0: skipped test because fstrim is not available\n";
+ exit 77;
+}
+
+# At this point we've got a disk which claims to support discard.
+# Let's test that theory.
+
+my $orig_size = (stat ($disk))[12];
+print "original size:\t$orig_size (blocks)\n";
+#system "du -sh $disk";
+
+# Write a filesystem onto the disk and fill it with data.
+
+$g->mkfs ("ext4", "/dev/sda");
+# Use nodiscard here so the 'rm' below doesn't discard data.
+$g->mount_options ("nodiscard", "/dev/sda", "/");
+$g->fill (33, 10000000, "/data");
+$g->sync ();
+
+my $full_size = (stat ($disk))[12];
+print "full size:\t$full_size (blocks)\n";
+#system "du -sh $disk";
+
+die "$0: surprising result: full size <= original size\n"
+ if $full_size <= $orig_size;
+
+# Remove the file and then try to trim the filesystem.
+
+$g->rm ("/data");
+$g->fstrim ("/");
+$g->sync ();
+$g->close ();
+
+my $trimmed_size = (stat ($disk))[12];
+print "trimmed size:\t$trimmed_size (blocks)\n";
+#system "du -sh $disk";
+
+die "$0: looks like the fstrim operation did not work\n"
+ if $trimmed_size >= $full_size;
--
1.8.5.3