Subject: | synopsis2.t relies on (unguaranteed) file order |
Test failure: synopsis2.t
Perl Version: 5.8.3
OS Version: Linux 2.6.7-1.494.2.2
Filesystem: ext3
uname -a: "Linux HOSTNAME 2.6.7-1.494.2.2 #1 Tue Aug 3 09:39:58 EDT 2004 i686 i686 i386 GNU/Linux"
Distribution: IO-All-0.31.tar.gz
Distro MD5: 9c8d8f6249db99f57ea903c44515a796
I was using cpan2rpm to build IO::All and ran into a test failure on
"t/synopsis2.t". Investigation revealed that the test was iterating
through the directory "t/mydir" and printing the filename and file
contents on successive lines.
However, the iteration through the filenames was not ordered, so the
order of these lines was dependent on the filesystem's arbitrary ordering
of their directory entries. As such, depending on the filesystem, the
test will repeatedly succeed or repeatedly fail, depending on which order
the files were placed into the directory. That causes the test to produce
erroneous failures.
As long as the expected output is in a hard-coded order, I would recommend
that we require that the directory traversal be in a known order. A
function exists to do that, IO::All::Dir::all(), so I would recommend
replacing the use of "$dir->next" with "$dir->all". (see patch)
To determine whether a "t/mydir" directory will produce this failure,
try "ls -f t/mydir" or "find t/mydir" and look at the order of the
files with names starting with "file". If they are in the order
file1,file2,file3, then the test should pass. Otherwise, an out-of-order
failure (see attached) should occur.
I'm not sure if it's possible to control the order of files under ext3,
as it may be determined by hashing of the filenames, so I have not been
able to generate a series of commands which creates in-order and
out-of-order test directories. However, this test is order-dependent,
and that should be changed.
overture-presto-179# diff -u t/synopsis2.t t/synopsis2.t-fixed
--- t/synopsis2.t 2004-05-27 01:44:55.000000000 -0700
+++ t/synopsis2.t-fixed 2004-08-23 15:36:54.949994808 -0700
@@ -8,7 +8,7 @@
# Print name and first line of all files in a directory
my $dir = io('t/mydir');
ok($dir->is_dir);
-while (my $io = $dir->next) {
+foreach my $io ($dir->all) {
if ($io->is_file) {
my $line = $io->name . ' - ' . $io->getline;
is($line, flip_slash scalar <DATA>);
overture-presto-180# perl t/synopsis2.t
1..10
ok 1
ok 2
not ok 3
# Failed test (t/synopsis2.t at line 14)
# got: 't/mydir/file3 - file3 is whee
# '
# expected: 't/mydir/file2 - file2 is woohoo
# '
not ok 4
# Failed test (t/synopsis2.t at line 14)
# got: 't/mydir/file2 - file2 is woohoo
# '
# expected: 't/mydir/file3 - file3 is whee
# '
ok 5
ok 6
ok 7
ok 8
ok 9
ok 10
# Looks like you failed 2 tests of 10.
overture-presto-181# perl t/synopsis2.t-fixed
1..10
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 9
ok 10