[Pkg-libvirt-commits] [libguestfs] 28/40: resize: Rewrite the tests to use a stochastic testing method.

Hilko Bengen bengen at moszumanska.debian.org
Fri Oct 3 14:49:14 UTC 2014


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag debian/1%1.27.57-1
in repository libguestfs.

commit 6f196df4145847659b81c91b7314fe7e0775ad94
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Mon Sep 29 14:45:13 2014 +0100

    resize: Rewrite the tests to use a stochastic testing method.
    
    The previous tests were very limited, and ran the same two tests
    on every run.
    
    Randomly test:
     - MBR vs GPT
     - Primary, extended partitions
     - Expanding vs shrinking
     - Use of multiple --resize parameters
     - Source and target raw vs qcow2 formats
     - Resizing various different filesystem types
     - LV expand
     - extra partition or no extra partition
    
    To run the test over and over again (useful for finding regressions in
    virt-resize), do:
    
      while (cd resize; LIBGUESTFS_TRACE=1 ../run ./test-virt-resize.pl) >&/tmp/log ; do echo -n .; done
    
    If it fails, you can see the failure in /tmp/log.
    
    To rerun a specific test, search for the 'seed:' in the output of the
    original test, and specify it on the command line:
    
      (cd resize; ../run ./test-virt-resize.pl --seed=<SEED>)
---
 po/POTFILES                |   1 +
 resize/Makefile.am         |   4 +-
 resize/test-virt-resize.pl | 354 +++++++++++++++++++++++++++++++++++++++++++++
 resize/test-virt-resize.sh |  62 --------
 4 files changed, 357 insertions(+), 64 deletions(-)

diff --git a/po/POTFILES b/po/POTFILES
index be2de28..1a088f5 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -273,6 +273,7 @@ python/guestfs-py-byhand.c
 python/guestfs-py.c
 rescue/rescue.c
 rescue/test-virt-rescue.pl
+resize/test-virt-resize.pl
 ruby/ext/guestfs/_guestfs.c
 sparsify/statvfs-c.c
 src/actions-0.c
diff --git a/resize/Makefile.am b/resize/Makefile.am
index d1bc46f..eb4ded3 100644
--- a/resize/Makefile.am
+++ b/resize/Makefile.am
@@ -20,7 +20,7 @@ include $(top_srcdir)/subdir-rules.mk
 EXTRA_DIST = \
 	$(SOURCES) \
 	virt-resize.pod \
-	test-virt-resize.sh
+	test-virt-resize.pl
 
 CLEANFILES = *~ *.cmi *.cmo *.cmx *.cmxa *.o virt-resize
 
@@ -136,7 +136,7 @@ TESTS_ENVIRONMENT = $(top_builddir)/run --test
 
 TESTS =
 if ENABLE_APPLIANCE
-TESTS += test-virt-resize.sh
+TESTS += test-virt-resize.pl
 endif
 
 check-valgrind:
diff --git a/resize/test-virt-resize.pl b/resize/test-virt-resize.pl
new file mode 100755
index 0000000..7c8faf9
--- /dev/null
+++ b/resize/test-virt-resize.pl
@@ -0,0 +1,354 @@
+#!/usr/bin/perl -w
+# Copyright (C) 2010-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.
+
+# Stochastic testing of virt-resize.
+
+use strict;
+use warnings;
+
+use Getopt::Long;
+
+use Sys::Guestfs;
+
+if ($ENV{SKIP_TEST_VIRT_RESIZE_PL}) {
+    print "$0: test skipped because environment variable is set\n";
+    exit 77
+}
+
+# So srand returns the seed.
+if ($] < 5.014) {
+    print "$0: test skipped because perl < 5.14\n";
+    exit 77
+}
+
+# Byte calculations go screwy on 32 bit.
+if (~1 == 4294967294) {
+    print "$0: this program does not work on a 32 bit host\n";
+    exit 77
+}
+
+# Command line arguments.
+my $help = 0;
+my $seed = 0;
+GetOptions ("help|?" => \$help,
+            "seed=i" => \$seed);
+if ($help) {
+    print "$0 [--seed=SEED]\n";
+    print "  --seed=SEED       Set the starting seed (to reproduce a test)\n";
+    exit 0
+}
+
+if ($seed == 0) {
+    # Choose a random seed.
+    $seed = srand ();
+}
+else {
+    # User specified --seed option.
+    srand ($seed);
+}
+
+$| = 1;
+
+my $g = Sys::Guestfs->new ();
+my $backend = $g->get_backend ();
+
+# Choose a random test.
+my $part_type = "mbr";
+if (rand () <= 0.5) {
+    $part_type = "gpt"
+}
+# If $nr_parts >= 4 && $part_type = "mbr" then this implies creating
+# an extended partition (#4) and zero or more logical partitions.
+my $nr_parts = 1 + int (rand (7));
+# expand (1) or shrink (0)
+my $expand = 0;
+if (rand () >= 0.2) {
+    $expand = 1;
+}
+my $source_format = "raw";
+if ($backend ne "uml" && rand () < 0.2) {
+    $source_format = "qcow2";
+}
+my $target_format = "raw";
+if ($backend ne "uml" && rand () < 0.2) {
+    $target_format = "qcow2";
+}
+my $no_extra_partition = 0;
+if ($part_type eq "mbr" && $nr_parts > 3) {
+    $no_extra_partition = 1;
+}
+if ($expand && rand () < 0.5) {
+    $no_extra_partition = 1;
+}
+
+# Print the test before starting, so it will appear in failure output.
+print "seed:           $seed\n";
+print "partition type: $part_type\n";
+print "nr partitions:  $nr_parts\n";
+print "expand:         $expand\n";
+print "no extra part:  $no_extra_partition\n";
+print "source format:  $source_format\n";
+print "target format:  $target_format\n";
+
+# Make a structure for each partition, recording what it will contain
+# and whether we will --resize / --expand / --shrink it.
+# Note this array is numbered from 1!
+my @parts;
+my $i;
+for ($i = 1; $i <= $nr_parts; ++$i) {
+    $parts[$i] = { name => "sda".$i, resize => 0 };
+
+    if ($part_type eq "mbr") {
+        if ($i < 4) {
+            if (rand () < 0.5) {
+                $parts[$i]->{resize} = 1;
+            }
+        } elsif ($i == 4) {
+            $parts[$i]->{content} = "extended";
+        }
+    } else {
+        if (rand () < 0.5) {
+            $parts[$i]->{resize} = 1;
+        }
+    }
+}
+
+# Pick a partition at random to expand or shrink.
+if ($part_type eq "mbr") {
+    # virt-resize cannot shrink extended or logical partitions, so we
+    # set $max so that these cannot be chosen:
+    my $max = 3;
+    $max = $nr_parts if $max > $nr_parts;
+    $i = 1 + int (rand ($max));
+} else {
+    $i = 1 + int (rand ($nr_parts));
+}
+$parts[$i]->{resize} = 0;
+$parts[$i]->{expand_shrink} = 1;
+
+# Size of the source disk.  It's always roughly nr_parts * size of
+# each partition + a bit extra.  For btrfs we have to choose a large
+# partition size.
+my $source_size = (10 + $nr_parts * 512) * 1024 * 1024;
+
+# Create the source disk.
+my $source_file = "test-virt-resize-source.img";
+$g->disk_create ($source_file, $source_format, $source_size);
+$g->add_drive ($source_file, format => $source_format);
+$g->launch ();
+
+# After launching we can detect if various filesystem types are
+# supported and use that to further parameterize the test.
+my $vfs_type = "ext2";
+my $r = rand ();
+if ($r < 0.15) {
+    $vfs_type = "lvm";
+} elsif ($r < 0.30) {
+    if ($g->feature_available (["ntfs3g", "ntfsprogs"])) {
+        $vfs_type = "ntfs"
+    }
+} elsif ($r < 0.45) {
+    if ($g->filesystem_available ("btrfs")) {
+        $vfs_type = "btrfs"
+    }
+} elsif ($r < 0.60) {
+    # XFS cannot shrink.
+    if ($expand && $g->filesystem_available ("xfs")) {
+        $vfs_type = "xfs"
+    }
+}
+
+print "filesystem:     $vfs_type\n";
+
+my $lv_expand = "";
+if ($vfs_type eq "lvm" && $expand && rand () < 0.5) {
+    $lv_expand = "/dev/VG/LV";
+}
+print "LV expand:      $lv_expand\n";
+
+for ($i = 1; $i <= $nr_parts; ++$i) {
+    $parts[$i]->{content} = $vfs_type unless exists $parts[$i]->{content};
+}
+
+for ($i = 1; $i <= $nr_parts; ++$i) {
+    printf "partition %d:    %s %s ", $i, $parts[$i]->{name}, $parts[$i]->{content};
+    if ($parts[$i]->{resize}) {
+        print "resize"
+    } elsif ($parts[$i]->{expand_shrink}) {
+        if ($expand) {
+            print "expand"
+        }
+        else {
+            print "shrink"
+        }
+    } else {
+        print "-";
+    }
+    print "\n";
+}
+
+# Create the source disk partitions.
+$g->part_init ("/dev/sda", $part_type);
+my $start = 2048;
+
+if ($part_type eq "gpt") {
+    for (my $i = 1; $i <= $nr_parts; ++$i) {
+        my $end = $start + 1024*1024 - 1;
+        $g->part_add ("/dev/sda", "primary", $start, $end);
+        $start = $end+1;
+    }
+} else {
+    # MBR is nuts ...
+    for ($i = 1; $i <= $nr_parts; ++$i) {
+        if ($i <= 3) {
+            my $end = $start + 1024*1024 - 1;
+            $g->part_add ("/dev/sda", "primary", $start, $end);
+            $start = $end+1;
+        }
+        elsif ($i == 4) {
+            # Extended partition is a container, so it just stretches
+            # to the end of the disk.
+            $g->part_add ("/dev/sda", "extended", $start, -2048);
+            $start += 1024;
+        }
+        else {
+            # Logical partitions sit inside the container, but the
+            # confusing thing about them is we have to take into
+            # account the sector that contains the linked list of
+            # logical partitions, hence -2/+2 below.
+            my $end = $start + 1024*1024 - 2;
+            $g->part_add ("/dev/sda", "logical", $start, $end);
+            $start = $end+2;
+        }
+    }
+}
+
+# Create the filesystem content.
+for ($i = 1; $i <= $nr_parts; ++$i) {
+    my $dev = "/dev/" . $parts[$i]->{name};
+    my $content = $parts[$i]->{content};
+    if ($content eq "extended") {
+        # do nothing - it's the extended partition
+    } elsif ($content eq "lvm") {
+        $g->pvcreate ($dev);
+        # If shrinking, shrink the PV to < 260MB.
+        if (!$expand) {
+            $g->pvresize_size ($dev, 256 * 1024 * 1024);
+        }
+    } else {
+        $g->mkfs ($content, $dev);
+        # If shrinking, shrink the filesystem to < 260MB.
+        if (!$expand) {
+            if ($content eq "ext2") {
+                $g->resize2fs_size ($dev, 256 * 1024 * 1024);
+            } elsif ($content eq "btrfs") {
+                $g->mount ($dev, "/");
+                $g->btrfs_filesystem_resize ("/", size => 256 * 1024 * 1024);
+                $g->umount_all ();
+            } elsif ($content eq "ntfs") {
+                $g->ntfsresize ($dev, size => 256 * 1024 * 1024);
+            } else {
+                die "internal error: content = $content";
+            }
+        }
+    }
+}
+
+# For LVM, create the LV.
+if ($vfs_type eq "lvm") {
+    my @pvs = $g->pvs ();
+    $g->vgcreate ("VG", \@pvs);
+    $g->lvcreate ("LV", "VG", 256);
+    $g->mkfs ("ext2", "/dev/VG/LV");
+}
+
+# Close the source.
+$g->shutdown ();
+$g->close ();
+
+# What size should the target be?  It depends on how many partitions
+# will be resized.
+my $target_size = 0;
+for ($i = 1; $i <= $nr_parts; ++$i) {
+    if ($parts[$i]->{resize} || $parts[$i]->{expand_shrink}) {
+        if ($expand) {
+            $target_size += 800;
+        } else {
+            $target_size += 260;
+        }
+    } else {
+        $target_size += 512; # remain at original size
+    }
+}
+$target_size += 10;
+$target_size *= 1024 * 1024;
+
+# Create the empty target container.
+my $target_file = "test-virt-resize-target.img";
+Sys::Guestfs->new ()->disk_create ($target_file, $target_format, $target_size);
+
+# Create the virt-resize command.
+my @command = (
+    "virt-resize",
+    "--format", $source_format,
+    "--output-format", $target_format,
+    );
+
+if ($vfs_type eq "ntfs") {
+    push @command, "--ntfsresize-force"
+}
+
+for ($i = 1; $i <= $nr_parts; ++$i) {
+    my $dev = "/dev/" . $parts[$i]->{name};
+    if ($expand) {
+        if ($parts[$i]->{resize}) {
+            push @command, "--resize", $dev."=+256M";
+        } else {
+            if ($parts[$i]->{expand_shrink}) {
+                push @command, "--expand", $dev;
+            }
+        }
+    } else { # shrink
+        if ($parts[$i]->{resize}) {
+            push @command, "--resize", $dev."=-256M";
+        } else {
+            if ($parts[$i]->{expand_shrink}) {
+                push @command, "--shrink", $dev;
+            }
+        }
+    }
+}
+
+if ($lv_expand) {
+    push @command, "--lvexpand", $lv_expand
+}
+
+if ($no_extra_partition) {
+    push @command, "--no-extra-partition"
+}
+
+push @command, $source_file, $target_file;
+
+print (join(" ", @command), "\n");
+
+system (@command) == 0 or die "command: '@command' failed: $?\n";
+
+# Clean up.
+unlink $source_file;
+unlink $target_file;
+
+exit 0
diff --git a/resize/test-virt-resize.sh b/resize/test-virt-resize.sh
deleted file mode 100755
index 9a1c24f..0000000
--- a/resize/test-virt-resize.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/bash -
-# libguestfs virt-resize 2.0 test script
-# Copyright (C) 2010-2012 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.
-
-export LANG=C
-set -e
-
-if [ "$(guestfish get-backend)" = "uml" ]; then
-    echo "$0: skipping test because uml backend does not support qcow2"
-    exit 77
-fi
-
-# Test expanding.
-#
-# This exercises a number of interesting codepaths including resizing
-# LV content, handling GPT, and using qcow2 as a target.
-
-$VG guestfish \
-    -N test-virt-resize-1.img=bootrootlv:/dev/VG/LV:ext2:ext4:400M:32M:gpt </dev/null
-
-$VG guestfish \
-    disk-create test-virt-resize-2.img qcow2 500M preallocation:metadata
-
-$VG virt-resize -d --debug-gc \
-    --expand /dev/sda2 \
-    --lv-expand /dev/VG/LV \
-    --format raw --output-format qcow2 \
-    test-virt-resize-1.img test-virt-resize-2.img
-
-# Test shrinking in a semi-realistic scenario.  Although the disk
-# image created above contains no data, we will nevertheless use
-# similar operations to ones that might be used by a real admin.
-
-guestfish -a test-virt-resize-1.img <<EOF
-run
-resize2fs-size /dev/VG/LV 190M
-lvresize /dev/VG/LV 190
-pvresize-size /dev/sda2 200M
-fsck ext4 /dev/VG/LV
-EOF
-
-rm -f test-virt-resize-2.img; guestfish sparse test-virt-resize-2.img 300M
-$VG virt-resize -d --debug-gc \
-    --shrink /dev/sda2 \
-    --format raw --output-format raw \
-    test-virt-resize-1.img test-virt-resize-2.img
-
-rm test-virt-resize-1.img test-virt-resize-2.img

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git



More information about the Pkg-libvirt-commits mailing list