summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/one.test112
-rwxr-xr-xtest/run226
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;
+ }
+}
+