[Pancutan-commits] r68 - in pancutan: . lib/Pancutan tests/lib/Pancutan/Test

tincho-guest at alioth.debian.org tincho-guest at alioth.debian.org
Fri Aug 17 16:28:20 UTC 2007


Author: tincho-guest
Date: 2007-08-17 16:28:20 +0000 (Fri, 17 Aug 2007)
New Revision: 68

Modified:
   pancutan/lib/Pancutan/Config.pm
   pancutan/lib/Pancutan/Tests.pm
   pancutan/lib/Pancutan/Util.pm
   pancutan/pancutan
   pancutan/tests/lib/Pancutan/Test/Files.pm
   pancutan/tests/lib/Pancutan/Test/Meta.pm
Log:
- Replaced test_defs_glob for testdef_dir, that looks better.
- Eliminated *mount_command, now that's controlled by mount_method, for
  supporting UML.
- Modified mount/unmount routines: now the array of mounted volumes is
  controlled by Util.pm, and the unmount_all takes care of unmounting volumes
  (mounted withing the same process) and removing directories. This way, tests
  can mount extra volumes, even from forked processes. Now all processes call
  unmount_all() before exit.
- The signal handler now no longer kills itself. The only way out is exit() or
  die(), so the END block is always called. cleanup() is only called from
  there.
- Since all program termination is done via exits or dies, also destructors
  have a chance to run. Modifying all filehandlers to be my(), they get
  destroyed automatically in case of premature exit.


Modified: pancutan/lib/Pancutan/Config.pm
===================================================================
--- pancutan/lib/Pancutan/Config.pm	2007-08-17 01:32:57 UTC (rev 67)
+++ pancutan/lib/Pancutan/Config.pm	2007-08-17 16:28:20 UTC (rev 68)
@@ -24,16 +24,12 @@
 }
 
 my %default = (
-	tests_def_glob => "/usr/share/pancutan/tests/*.yaml",
+	testdef_dir => "/usr/share/pancutan/tests/",
 	concurrency => 2,
 	temp_dir => "",
 	continue_on_fatal => 0,
 	verbose => 0,
-    # Fuseiso9660 is SO slow...
-    #mount_command => 'fuseiso9660 %file %mntpnt',
-    #unmount_command => 'fusermount -u %mntpnt',
-    mount_command => 'sudo mount -oloop %file %mntpnt',
-    unmount_command => 'sudo umount %mntpnt',
+    mount_method => "sudomount",
 );
 
 my %validopts = map { $_ => 1 } keys %default;
@@ -44,10 +40,10 @@
 	%CONFIG = %default;
 	my $argv_opts = { };
 	GetOptions($argv_opts, "help|?", "config|c=s",
-		"tests_def_glob|tests-def-glob=s",
+		"testdef_dir|testdef-dir=s",
 		"concurrency|j=i", "temp_dir|temp-dir=s",
 		"continue_on_fatal|continue-on-fatal!",
-        "access_method|access-method|a=s",
+        "mount_method|mount-method|m=s",
 		"verbose|v:+") or exit(0); # For auto_version
     if($argv_opts->{help}) {
         main::help();
@@ -75,6 +71,9 @@
 			exists($validopts{$_}));
 		$CONFIG{$_} = $argv_opts->{$_};
 	}
+    unless($CONFIG{mount_method} =~ /^(sudomount|fuseiso9660|uml)$/) {
+        die "Unknown mount method: $CONFIG{mount_method}\n";
+    }
 	unless($CONFIG{temp_dir}) {
 		$CONFIG{temp_dir} = ".pancutan.$$";
 	}

Modified: pancutan/lib/Pancutan/Tests.pm
===================================================================
--- pancutan/lib/Pancutan/Tests.pm	2007-08-17 01:32:57 UTC (rev 67)
+++ pancutan/lib/Pancutan/Tests.pm	2007-08-17 16:28:20 UTC (rev 68)
@@ -29,7 +29,7 @@
 sub read_tests_meta {
     info("Reading test definitions");
     my @testdefs;
-    my @defs = glob $CONFIG{tests_def_glob};
+    my @defs = glob($CONFIG{testdef_dir} . "/*");
     unless(@defs) {
         die "Can't find any test definitions!\n";
     }

Modified: pancutan/lib/Pancutan/Util.pm
===================================================================
--- pancutan/lib/Pancutan/Util.pm	2007-08-17 01:32:57 UTC (rev 67)
+++ pancutan/lib/Pancutan/Util.pm	2007-08-17 16:28:20 UTC (rev 68)
@@ -10,7 +10,7 @@
 BEGIN {
     use Exporter ();
     our @ISA = qw(Exporter);
-    our @EXPORT = qw(execute debug info warnn mount umount);
+    our @EXPORT = qw(execute debug info warnn mount umount_all);
     our @EXPORT_OK   = qw(running queue_init run_task collect_results can_run);
     our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ],
         queue => [ @EXPORT_OK ] );
@@ -34,6 +34,7 @@
     my @argv = @_;
     my($fd, $res, @out);
     local $SIG{CHLD} = "DEFAULT";
+    local $?;
     my $pid = open($fd, "-|");
     unless(defined $pid) {
         die "Cannot fork: $!";
@@ -56,11 +57,51 @@
     return($res, @out) if(wantarray);
     return $res;
 }
+my %mntcmds = (
+    fuseiso9660 => {
+        mount => 'fuseiso9660 %file %mntpnt',
+        unmount => 'fusermount -u %mntpnt'
+    },
+    sudomount => {
+        mount => 'sudo mount -oloop %file %mntpnt',
+        mountdev => 'sudo mount %file %mntpnt',
+        unmount => 'sudo umount %mntpnt',
+    },
+    uml => {
+        mount => 'mount -oloop %file %mntpnt',
+        mountdev => 'mount %file %mntpnt',
+        unmount => 'umount %mntpnt',
+    }
+);
+my %mounts;
 sub mount {
-    return execute(replace_mount_cmd($CONFIG{mount_command}, @_));
+    my($file, $mntpnt) = @_;
+    mkdir $mntpnt or die $!;
+    my $mthd = $CONFIG{mount_method};
+    unless(exists $mntcmds{$mthd}) {
+        die "Unknown method $mthd\n";
+    }
+    my $cmd;
+    if(-b $file and exists $mntcmds{$mthd}{mountdev}) {
+        $cmd = $mntcmds{$mthd}{mountdev};
+    } else {
+        $cmd = $mntcmds{$mthd}{mount};
+    }
+    my $r = execute(replace_mount_cmd($cmd, $file, $mntpnt));
+    if($r) {
+        rmdir $mntpnt;
+        die "Error while mounting $file: $r\n";
+    }
+    push @{$mounts{$$}}, [ $file => $mntpnt ];
 }
-sub umount {
-    return execute(replace_mount_cmd($CONFIG{unmount_command}, @_));
+sub umount_all {
+    my $cmd = $mntcmds{$CONFIG{mount_method}}{unmount}
+        or die "Unknown method {$CONFIG{mount_method}\n";
+    foreach(@{$mounts{$$}}) {
+        my $r = execute(replace_mount_cmd($cmd, $_->[0], $_->[1]));
+        warn "Error while unmounting $_->[0]: $r\n" if($r);
+        rmdir $_->[1] or warn "Error removing directory: $!\n";
+    }
 }
 sub replace_mount_cmd {
     my($cmd, $file, $mntpnt) = @_;
@@ -137,6 +178,7 @@
             if($read) {
                 $q->{buf} .= $buf;
             } else {
+                local $?;
                 $select->remove($_);
                 close $_; # Close FD, perl does an implicit waitpid
                 $q->{done} = $?;
@@ -201,7 +243,7 @@
  warnn("This is a warning!");
  $result = execute("/bin/ls", "-l");
  $result = mount($iso, $mount_point");
- $result = umount($iso, $mount_point");
+ $result = umount_all();
 
  use Pancutan::Util qw(:queue);
  queue_init();
@@ -231,11 +273,12 @@
 
 =item B<mount> FILE MOUNT_POINT
 
-=item B<umount> FILE MOUNT_POINT
+Try to mount an ISO image, using the method set in the configuration file.
 
-Try to mount or unmount an ISO image, using the commands set in the
-configuration file.
+=item B<umount_all>
 
+Unmounts all the files that were mounted by the current process
+
 =item B<queue_init>
 
 Initialises the queue for parallel task management.

Modified: pancutan/pancutan
===================================================================
--- pancutan/pancutan	2007-08-17 01:32:57 UTC (rev 67)
+++ pancutan/pancutan	2007-08-17 16:28:20 UTC (rev 68)
@@ -13,7 +13,7 @@
 
 # Error codes
 my %error_t = (
-    fatal  => [ "F", 15 ],
+    fatal  => [ "F", 8 ],
     error  => [ "E", 4 ],
     "warn" => [ "W", 2 ]);
 
@@ -38,7 +38,9 @@
     die "$_ is a directory\n" if(-d $_);
     die "File is not readable: $_\n" unless(-r $_);
 }
-mkdir $CONFIG{temp_dir} or die "Cannot create temporary directory: $!\n";
+unless(-d $CONFIG{temp_dir}) {
+    mkdir $CONFIG{temp_dir} or die "Cannot create temporary directory: $!\n";
+}
 
 $SIG{HUP} = $SIG{INT} = $SIG{QUIT} = \&sighandler;
 $SIG{SEGV} = $SIG{PIPE} = $SIG{TERM} = \&sighandler;
@@ -48,9 +50,7 @@
 my $n = 0;
 foreach(@isos) {
     my $mntpt = "$CONFIG{temp_dir}/$n";
-    mkdir $mntpt or die $!;
-    my $r = mount($_, $mntpt);
-    die "Error while mounting $_: $r\n" if($r);
+    mount($_, $mntpt);
     $metadata->{set}[$n] = {
         file => $_,
         mount => $mntpt
@@ -145,7 +145,6 @@
         # perlfunc and perlipc
         kill INT => 0;
         while(wait() != -1) {}
-        cleanup();
     }
     die @_;
 }
@@ -153,28 +152,21 @@
     my $sig = shift;
     unless($i_am_a_fork) {
         warn "Caught $sig signal...\n";
-        $SIG{$sig} = "IGNORE";
+        $SIG{INT} = "IGNORE";
         # Kill the whole process group
-        kill $sig, 0;
+        kill INT => 0;
         while(wait() != -1) {}
-        cleanup();
     }
     # signal myself again
-    $SIG{$sig} = "DEFAULT";
-    kill $sig, $$;
+    #$SIG{$sig} = "DEFAULT";
+    #kill $sig, $$;
+    # Let it die(), so END{} is called
+    exit 16;
 }
 sub cleanup {
+    umount_all();
     return if($i_am_a_fork);
-    return unless(@{$metadata->{set}});
     info("Cleaning up");
-    foreach(@{$metadata->{set}}) {
-        my $r = umount($_->{file}, $_->{mount});
-        if ($r) {
-            warnn($r);
-        }
-        rmdir($_->{mount});
-    }
-    $metadata->{set} = [];
     rmdir $CONFIG{temp_dir};
 }
 sub help {
@@ -191,9 +183,11 @@
                             (2, use 0 for never forking)
      --verbose, -v [n]      Increase or set verbosity level
      --continue-on-fatal    Continue testing after a fatal error
-     --tests-def-glob GLOB  Glob for finding test defitions
-                            (/usr/share/pancutan/tests/*.yaml)
-     --temp-dir DIR         Temporary directory (.pancutan.$$)
+     --testdef-dir DIR      Directory for finding test defitions
+                            (/usr/share/pancutan/tests/)
+     --temp-dir DIR         Temporary directory (.pancutan.\$\$)
+     --mount_method METHOD  Specify which method to use to mount files:
+                            sudomount, fuseiso9660 or uml (sudomount)
 
 END
 }
@@ -235,14 +229,28 @@
 
 Continue testing after a fatal error
 
-=item B<--tests-def-glob> I<GLOB>
+=item B<--testdef-dir> I<DIR>
 
-Glob for finding test defitions (default: "/usr/share/pancutan/tests/*.yaml")
+Directory containing test definitions (default: "/usr/share/pancutan/tests/")
 
 =item B<--temp-dir> I<DIR>
 
 Temporary directory (default: ".pancutan.$$")
 
+=item B<--mount-method> sudomount | fuseiso9660 | uml
+
+Specifies which method to use for mounting the images, defaults to
+B<sudomount>.
+
+B<sudomount> uses the standard mount, calling sudo to gain root. It uses
+loopback devices when needed.
+
+B<fuseiso9660> uses the FUSE module to mount filesystems without root
+privileges. Requires FUSE and permission to run it.
+
+B<uml> runs the whole process inside an instance of user-mode-linux, and inside
+the virtual machine uses root privileges to execute mount as with B<sudomount>.
+
 =back
 
 =head1 DESCRIPTION
@@ -262,25 +270,14 @@
 
 =item B<continue_on_fatal>
 
-=item B<tests_def_glob>
+=item B<testdef_dir>
 
 =item B<temp_dir>
 
+=item B<mount_method>
+
 These parameters are the same as in the command line.
 
-=item B<mount_command>
-
-=item B<unmount_command>
-
-Those two parameters allow to define the commands for mounting and unmounting
-each ISO image. They can contain two parameters: %file and %mntpnt, which are
-replaced with the ISO file and the mount point. The default values for those
-parameters are:
-
-mount_command: fuseiso9660 %file %mntpnt
-
-unmount_command: fusermount -u %mntpnt
-
 =back
 
 =cut

Modified: pancutan/tests/lib/Pancutan/Test/Files.pm
===================================================================
--- pancutan/tests/lib/Pancutan/Test/Files.pm	2007-08-17 01:32:57 UTC (rev 67)
+++ pancutan/tests/lib/Pancutan/Test/Files.pm	2007-08-17 16:28:20 UTC (rev 68)
@@ -51,19 +51,20 @@
     my $basedir = $cd->{mount};
     my %chksums;
     foreach(@{$scratch->{filelist}}) {
-        unless(open(FILE, "<", "$basedir/$_")) {
+        my $fh;
+        unless(open($fh, "<", "$basedir/$_")) {
             return(["file-unreadable", "Error opening $_: $!"]);
         }
         my($buf, $r);
         my $md5 = Digest::MD5->new;
         my $sha1 = Digest::SHA->new(1);
         my $sha2 = Digest::SHA->new(256);
-        while($r = sysread(FILE, $buf, 2048)) {
+        while($r = sysread($fh, $buf, 2048)) {
             $md5->add($buf);
             $sha1->add($buf);
             $sha2->add($buf);
         }
-        close FILE;
+        close $fh;
         unless(defined $r) {
             return(["file-unreadable", "Error reading $_: $!"]);
         }
@@ -117,9 +118,10 @@
     foreach my $chkf (@chkfs) {
         debug("Verifying $chkf");
         my %verif = map { $chkf => undef } @{$scratch->{filelist}};
-        open(CHK, "<", "$basedir/$chkf") or return("file-unreadable",
+        my $fh;
+        open($fh, "<", "$basedir/$chkf") or return("file-unreadable",
             "Cannot open $chkf: $!");
-        while(<CHK>) {
+        while(<$fh>) {
             chomp;
             unless(/^([0-9a-f]+)\s+(.*)$/) {
                 push @res, "unparseable-checksum", $_;
@@ -139,7 +141,7 @@
             push @res, "missing-file-in-checksum-file",
             "$_ not listed in $chkf";
         }
-        close CHK;
+        close $fh;
     }
     return @res;
 }

Modified: pancutan/tests/lib/Pancutan/Test/Meta.pm
===================================================================
--- pancutan/tests/lib/Pancutan/Test/Meta.pm	2007-08-17 01:32:57 UTC (rev 67)
+++ pancutan/tests/lib/Pancutan/Test/Meta.pm	2007-08-17 16:28:20 UTC (rev 68)
@@ -23,10 +23,10 @@
             debug("Detected live CD");
         }
         if(-e "$mount/.disk/info") {
-            my $info;
-            open INFO, "<", "$mount/.disk/info"
-                and chomp($info = <INFO>);
-            close INFO;
+            my($info, $fh);
+            open $fh, "<", "$mount/.disk/info"
+                and chomp($info = <$fh>);
+            close $fh;
             debug("Detected debian-cd");
             if($info) {
                 $meta{type} = "dcd";




More information about the Pancutan-commits mailing list