diff options
-rw-r--r-- | test/one.test | 112 | ||||
-rwxr-xr-x | test/run | 226 |
2 files changed, 338 insertions, 0 deletions
diff --git a/test/one.test b/test/one.test new file mode 100644 index 0000000..5f7d2b4 --- /dev/null +++ b/test/one.test @@ -0,0 +1,112 @@ +# This is a minimal test script that runs a few quilt commands +# and verifies their output. Much needs to be done; particularly +# it sould be possible to run the tests using the built instead +# of the installed quilt with `make check'. +# +# (To run, type `./run one.test' in this directory.) +# +$ mkdir dir +$ echo "This is file one." > dir/file1 +$ quilt new patch1.diff +Patch patch1 is now on top +$ quilt add dir/file1 +File dir/file1 added to patch patch1 +$ quilt add file2 +File file2 added to patch patch1 +$ quilt diff +$ quilt diff -z +$ quilt refresh +Nothing in patch patch1 +$ quilt files +dir/file1 +file2 +$ echo "This is file two." > file2 +$ quilt diff | sed -e "s/\\t.*//" +Index: test/file2 +--- test~patch1/file2 ++++ test/file2 +@@ -0,0 +1 @@ ++This is file two. +$ quilt diff -z | sed -e "s/\\t.*//" +Index: test/file2 +--- test.orig/file2 ++++ test/file2 +@@ -0,0 +1 @@ ++This is file two. +$ quilt refresh +Refreshed patch patch1 +$ quilt diff -z +$ echo "Another line has been added." >> dir/file1 +$ quilt diff -z | sed -e "s/\\t.*//" +Index: test/dir/file1 +--- test.orig/dir/file1 ++++ test/dir/file1 +@@ -1 +1,2 @@ + This is file one. ++Another line has been added. +$ quilt refresh +Refreshed patch patch1 +$ quilt new patch2.diff +Patch patch2 is now on top +$ quilt add dir/file3 +File dir/file3 added to patch patch2 +$ echo "This is file three." > dir/file3 +$ quilt refresh +Refreshed patch patch2 +$ quilt add -p patch1 dir/file3 +File dir/file3 modified by patch patch2 +$ quilt pop +Removing dir/file3 +Removed patch2, now at patch1 + +$ quilt add file4 +File file4 added to patch patch1 +$ echo "This is file 4." > file4 +$ quilt refresh +Refreshed patch patch1 +$ quilt push +Applying patch2 +patching file dir/file3 + +$ quilt new subdir/patch3.diff +Patch subdir/patch3 is now on top +$ quilt add file4 +File file4 added to patch subdir/patch3 +$ rm file4 +$ quilt diff | sed -e "s/\\t.*//" +Index: test/file4 +--- test~subdir_patch3/file4 ++++ test/file4 +@@ -1 +0,0 @@ +-This is file 4. +$ quilt add -p patch2 file4 +File file4 modified by patch subdir/patch3 +$ quilt refresh +Refreshed patch subdir/patch3 +$ echo "Another line here, too." >> dir/file3 +$ quilt refresh patch2 +Refreshed patch patch2 +$ echo "Another line added." >> file2 +$ quilt diff -z -P patch1 | sed -e "s/\\t.*//" +Index: test/file2 +--- test.orig/file2 ++++ test/file2 +@@ -1 +1,2 @@ + This is file two. ++Another line added. +More recent patches modify files in patch1. +$ quilt refresh patch1 +More recent patches modify files in patch1. Enforce refresh with -f. +$ quilt refresh -f patch1 +Refreshed patch patch1 +$ echo "Another line here, too." >> dir/file3 +$ quilt pop +patching file file4 +Removed subdir/patch3, now at patch2 + +$ quilt refresh patch2 +Refreshed patch patch2 +$ quilt pop -qa +Removed patch2, now at patch1 +Removed patch1, no patches applied +$ rm -r dir patches diff --git a/test/run b/test/run new file mode 100755 index 0000000..c6d09f6 --- /dev/null +++ b/test/run @@ -0,0 +1,226 @@ +#! /usr/bin/perl -w -U + +use strict; +use FileHandle; +use Getopt::Std; +use POSIX qw(isatty setuid); +use vars qw($opt_v); + +no warnings qw(taint); + +getopts('v'); + +my ($OK, $FAILED) = ("ok", "failed"); +if (isatty(fileno(STDOUT))) { + $OK = "\033[32m" . $OK . "\033[m"; + $FAILED = "\033[31m\033[1m" . $FAILED . "\033[m"; +} + +sub exec_test($$); + +my ($prog, $in, $out) = ([], [], []); +my $line = 0; +my $prog_line; +my ($tests, $failed) = (0,0); + +for (;;) { + my $script = <>; $line++; + if (defined $script) { + # Substitute %VAR and %{VAR} with environment variables. + $script =~ s[%(?:(\w+)|\{(\w+)\})][$ENV{"$1$2"}]eg; + } + next if (defined($script) && $script =~ /^!/); + if (!defined($script) || $script =~ s/^\$ ?//) { + if (@$prog) { + #print "[$prog_line] \$ ", join(' ', @$prog), " -- "; + my $p = [ @$prog ]; + print "[$prog_line] \$ ", join(' ', + map { s/\s/\\$&/g; $_ } @$p), " -- "; + my $result = exec_test($prog, $in); + my $good = 1; + my $nmax = (@$out > @$result) ? @$out : @$result; + for (my $n=0; $n < $nmax; $n++) { + if (!defined($out->[$n]) || !defined($result->[$n]) || + $out->[$n] ne $result->[$n]) { + $good = 0; + #chomp $out->[$n]; + #chomp $result->[$n]; + #print "$out->[$n] != $result->[$n]"; + } + } + $tests++; + $failed++ unless $good; + print $good ? $OK : $FAILED, "\n"; + if (!$good) { + for (my $n=0; $n < $nmax; $n++) { + my $l = defined($out->[$n]) ? $out->[$n] : "~"; + chomp $l; + my $r = defined($result->[$n]) ? $result->[$n] : "~"; + chomp $r; + print sprintf("%-37s | %-39s\n", $l, $r); + } + } elsif ($opt_v) { + print join('', @$result); + } + } + #$prog = [ split /\s+/, $script ] if $script; + $prog = [ map { s/\\(.)/$1/g; $_ } split /(?<!\\)\s+/, $script ] if $script; + $prog_line = $line; + $in = []; + $out = []; + } elsif ($script =~ s/^> ?//) { + push @$in, $script; + } else { + push @$out, $script; + } + last unless defined($script); +} +my $status = sprintf("%d commands (%d passed, %d failed)", + $tests, $tests-$failed, $failed); +if (isatty(fileno(STDOUT))) { + if ($failed) { + $status = "\033[31m\033[1m" . $status . "\033[m"; + } else { + $status = "\033[32m" . $status . "\033[m"; + } +} +print $status, "\n"; +exit $failed ? 1 : 0; + +sub su($) { + my ($user) = @_; + + my ($login, $pass, $uid, $gid) = getpwnam($user) + or return [ "su: user $prog->[1] does not exist\n" ]; + my @groups = (); + my $fh = new FileHandle("/etc/group") + or return [ "opening /etc/group: $!\n" ]; + while (<$fh>) { + chomp; + my ($group, $passwd, $gid, $users) = split /:/; + foreach my $u (split /,/, $users) { + push @groups, $gid + if ($user eq $u); + } + } + $fh->close; + + my $groups = join(" ", ($gid, $gid, @groups)); + #print STDERR "[[$groups]]\n"; + $> = 0; + $( = $gid; + $) = $groups; + if ($!) { + return [ "setgroups: $!\n" ]; + } + if ($uid != 0) { + $> = $uid; + #$< = $uid; + if ($!) { + return [ "seteuid: $prog->[1]: $!\n" ]; + } + } + #print STDERR "[($>,$<)($(,$))]"; + return []; +} + +sub exec_test($$) { + my ($prog, $in) = @_; + local (*IN, *IN_DUP, *IN2, *OUT_DUP, *OUT, *OUT2); + my $needs_shell = (join('', @$prog) =~ /[|<>"'`\$]/); + + if ($prog->[0] eq "umask") { + umask oct $prog->[1]; + return []; + } elsif ($prog->[0] eq "cd") { + if (!chdir $prog->[1]) { + return [ "chdir: $prog->[1]: $!\n" ]; + } + return []; + } elsif ($prog->[0] eq "su") { + return su($prog->[1]); + } elsif ($prog->[0] eq "seteuid") { + my $user = $prog->[1]; + my ($login,$pass,$uid,$gid) = getpwnam($user) or + return [ "seteuid: user $prog->[1] does not exist\n" ]; + $> = $uid; + if ($> != $uid) { + return [ "seteuid: $prog->[1]: $!\n" ]; + } + return []; + } + + pipe *IN2, *OUT + or die "Can't create pipe for reading: $!"; + open *IN_DUP, "<&STDIN" + or *IN_DUP = undef; + open *STDIN, "<&IN2" + or die "Can't duplicate pipe for reading: $!"; + close *IN2; + + open *OUT_DUP, ">&STDOUT" + or die "Can't duplicate STDOUT: $!"; + pipe *IN, *OUT2 + or die "Can't create pipe for writing: $!"; + open *STDOUT, ">&OUT2" + or die "Can't duplicate pipe for writing: $!"; + close *OUT2; + + *STDOUT->autoflush(); + *OUT->autoflush(); + + if (fork()) { + # Server + if (*IN_DUP) { + open *STDIN, "<&IN_DUP" + or die "Can't duplicate STDIN: $!"; + close *IN_DUP + or die "Can't close STDIN duplicate: $!"; + } + open *STDOUT, ">&OUT_DUP" + or die "Can't duplicate STDOUT: $!"; + close *OUT_DUP + or die "Can't close STDOUT duplicate: $!"; + + foreach my $line (@$in) { + #print "> $line"; + print OUT $line; + } + close *OUT + or die "Can't close pipe for writing: $!"; + + my $result = []; + while (<IN>) { + #print "< $_"; + if ($needs_shell) { + s#^/bin/sh: line \d+: ##; + } + push @$result, $_; + } + return $result; + } else { + # Client + $< = $>; + close IN + or die "Can't close read end for input pipe: $!"; + close OUT + or die "Can't close write end for output pipe: $!"; + close OUT_DUP + or die "Can't close STDOUT duplicate: $!"; + local *ERR_DUP; + open ERR_DUP, ">&STDERR" + or die "Can't duplicate STDERR: $!"; + open STDERR, ">&STDOUT" + or die "Can't join STDOUT and STDERR: $!"; + + #print ERR_DUP "<", join(' ', @$prog), ">\n"; + if ($needs_shell) { + exec ('/bin/sh', '-c', join(" ", @$prog)); + } else { + exec @$prog; + } + print ERR_DUP $prog->[0], ": $!\n"; + exit; + } +} + |