testing/fstest: TestFS
falsely fails for certain directory trees on macOS
#54795
Labels
help wanted
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
OS-Darwin
Milestone
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yep! I've also tested it with 1.17.13 and 1.18.5.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
On a macOS host, create this
testdata/
tree. The file contents don't matter, only the hierarchy and file names are important:Then run the following test
What did you expect to see?
The
dirfs - bug
test case should pass, because all expected files exist undertestdata/bug
. Themapfs
test case at least proves thatfstest.TestFS
can handle a file tree like this, because it always passes.What did you see instead?
The
dirfs - bug
test case fails on macOS, with an error case I like to call "Schrödinger's bar":But always passes on linux:
Analysis
This one fails (on darwin), but we'd expect it not to. All expected files exist in that test directory. The checks at the end of
fstester.checkGlob
rely on bothnames
andwant
being sorted, but it only checks thatnames
is sorted. The ordering ofwant
is dependent on whatReadDirFile.ReadDir
returns here and, foros.DirFS
, that ordering is platform dependent. The docs forReadDirFile.ReadDir
say to the files being returned in "directory order":There are consistency checks in
fstester.checkDir
for reading the dir entries before checking the glob, but these fail to prevent the ordering issue andlist
ultimately ends up aswant
. The closest this come to checkinglist
's order is checking that the elements match with whatfs.ReadDir
returns (which islist2
) and then checking thatlist2
is sorted. Passinglist2
intot.checkGlob
would likely fix the issue because it is guaranteed to be sorted.This only happens when there are at least two paths in the same directory that match the internally computed glob. In this test, both
sub/bar
andsub/paths
match glob*a*
insub/
. Obviously if there is only one path that matches the glob, the ordering doesn't matter.In this test case (on darwin), you end up with the following state at the want/names check here:
want = ["paths", "bar"]
names = ["bar", "paths"]
That code doesn't properly compare two unsorted slices, and so you end with the error:
The text was updated successfully, but these errors were encountered: