*** empty log message ***
[coreutils.git] / tests / ls-2 / T.pm
blob6c8fa0d08faf4dc8a2c0d74cecc39c4ef7628e04
1 package T;
3 require 5.004;
4 use strict;
5 use vars qw($VERSION @ISA @EXPORT);
7 use FileHandle;
8 use File::Compare qw(compare);
10 @ISA = qw(Exporter);
11 $VERSION = '0.5';
12 @EXPORT = qw (run_tests);
14 my @Types = qw (IN OUT ERR EXIT);
15 my %Types = map {$_ => 1} @Types;
16 my %Zero_one_type = map {$_ => 1} qw (OUT ERR EXIT);
18 my $Global_count = 1;
20 sub _create_file ($$$$$)
22 my ($program_name, $test_name, $type, $file_name, $data) = @_;
23 my $file;
24 if (defined $file_name)
26 $file = $file_name;
28 else
30 $file = "$test_name-$$.$Global_count";
31 ++$Global_count;
34 # The test spec gave a string.
35 # Write it to a temp file and return tempfile name.
36 #warn "writing $type `$data' to $file\n";
37 my $fh = new FileHandle "> $file";
38 die "$program_name: $file: $!\n" if ! $fh;
39 print $fh $data;
40 $fh->close || die "$program_name: $file: $!\n";
42 return $file;
45 # FIXME: cleanup on interrupt
46 # FIXME: extract `do_1_test' function
48 # FIXME: having to include $program_name here is an expedient kludge.
49 # Library code doesn't `die'.
50 sub run_tests ($$$$$)
52 my ($program_name, $prog, $t_spec, $save_temps, $verbose) = @_;
54 # Warn about empty t_spec.
55 # FIXME
57 # Remove all temp files upon interrupt.
58 # FIXME
60 # Verify that test names are distinct.
61 my $found_duplicate = 0;
62 my %seen;
63 my $t;
64 foreach $t (@$t_spec)
66 my $test_name = $t->[0];
67 if ($seen{$test_name})
69 warn "$program_name: $test_name: duplicate test name\n";
70 $found_duplicate = 1;
72 $seen{$test_name} = 1;
74 return 1 if $found_duplicate;
76 # FIXME check exit status
77 system ($prog, '--version');
79 my @junk_files;
80 my $fail = 0;
81 foreach $t (@$t_spec)
83 my $test_name = shift @$t;
84 my $expect = {};
86 $Global_count = 1;
87 my @args;
88 my $io_spec;
89 my %seen_type;
90 foreach $io_spec (@$t)
92 if (!ref $io_spec)
94 push @args, $io_spec;
95 next;
98 die "$program_name: $test_name: invalid test spec\n"
99 if ref $io_spec ne 'HASH';
101 my $n = keys %$io_spec;
102 die "$program_name: $test_name: spec has $n elements --"
103 . " expected 1\n"
104 if $n != 1;
105 my ($type, $val) = each %$io_spec;
106 die "$program_name: $test_name: invalid key `$type' in test spec\n"
107 if ! $Types{$type};
109 # Make sure there's no more than one of OUT, ERR, EXIT.
110 die "$program_name: $test_name: more than one $type spec\n"
111 if $Zero_one_type{$type} and $seen_type{$type}++;
113 if ($type eq 'EXIT')
115 # FIXME: make sure $data is numeric
116 $expect->{EXIT} = $val;
117 next;
120 my $file_spec = $val;
121 my ($file_name, $contents);
122 if (!ref $file_spec)
124 ($file_name, $contents) = (undef, $file_spec);
126 elsif (ref $file_spec eq 'HASH')
128 my $n = keys %$file_spec;
129 die "$program_name: $test_name: $type spec has $n elements --"
130 . " expected 1\n"
131 if $n != 1;
132 ($file_name, $contents) = each %$file_spec;
134 else
136 die "$program_name: $test_name: invalid RHS in $type-spec\n"
139 my $is_junk_file = (! defined $file_name);
140 my $file = _create_file ($program_name, $test_name, $type,
141 $file_name, $contents);
142 if ($type eq 'IN')
144 push @args, $file
146 else
148 $expect->{$type} = $file;
151 if ($is_junk_file)
153 push @junk_files, $file
155 else
157 # FIXME: put $srcdir in here somewhere
158 warn "$program_name: $test_name: specified file `$file' does"
159 . " not exist\n"
160 if ! -f $file;
164 # Expect an exit status of zero if it's not specified.
165 $expect->{EXIT} ||= 0;
167 # Allow ERR to be omitted -- in that case, expect no error output.
168 my $eo;
169 foreach $eo (qw (ERR OUT))
171 if (!exists $expect->{$eo})
173 $expect->{$eo} = _create_file ($program_name, $test_name, $eo,
174 undef, '');
175 push @junk_files, $expect->{$eo};
179 # FIXME: Require at least one of OUT_DATA, OUT_FILE. Why?
181 warn "$test_name...\n";
182 my $t_out = "$test_name-out";
183 my $t_err = "$test_name-err";
184 push (@junk_files, $t_out, $t_err);
185 my @cmd = ($prog, @args, "> $t_out", "2> $t_err");
186 my $cmd_str = join (' ', @cmd);
187 warn "Running command: `$cmd_str'\n" if $verbose;
188 my $rc = 0xffff & system $cmd_str;
189 if ($rc == 0xff00)
191 warn "$program_name: test $test_name failed: command failed:\n"
192 . " `$cmd_str': $!\n";
193 $fail = 1;
194 next;
196 $rc >>= 8 if $rc > 0x80;
197 if ($expect->{EXIT} != $rc)
199 warn "$program_name: test $test_name failed: exit status mismatch:"
200 . " expected $expect->{EXIT}, got $rc\n";
201 $fail = 1;
202 next;
205 if (compare ($expect->{OUT}, $t_out))
207 warn "$program_name: stdout mismatch, comparing"
208 . " $expect->{OUT} and $t_out\n";
209 $fail = 1;
210 next;
212 if (compare ($expect->{ERR}, $t_err))
214 warn "$program_name: stderr mismatch, comparing"
215 . " $expect->{ERR} and $t_err\n";
216 $fail = 1;
217 next;
221 unlink @junk_files if ! $save_temps;
223 return $fail;
226 ## package return