Skip to content

Commit 0aa65ed

Browse files
committed
Fix sorting in IOFS.ReadDir
We recently added a check for fs.ReadDirFile in IOFS.ReadDir, but forgot to apply a sort to the result as defined in the spec. This fixes that and adds a test case for it.
1 parent b0a534a commit 0aa65ed

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

iofs.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,12 @@ func (iofs IOFS) ReadDir(name string) ([]fs.DirEntry, error) {
7676
defer f.Close()
7777

7878
if rdf, ok := f.(fs.ReadDirFile); ok {
79-
return rdf.ReadDir(-1)
79+
items, err := rdf.ReadDir(-1)
80+
if err != nil {
81+
return nil, iofs.wrapError("readdir", name, err)
82+
}
83+
sort.Slice(items, func(i, j int) bool { return items[i].Name() < items[j].Name() })
84+
return items, nil
8085
}
8186

8287
items, err := f.Readdir(-1)

iofs_test.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"io"
1111
"io/fs"
12+
"math/rand"
1213
"os"
1314
"path/filepath"
1415
"runtime"
@@ -76,7 +77,17 @@ func TestIOFSNativeDirEntryWhenPossible(t *testing.T) {
7677
t.Fatal(err)
7778
}
7879

79-
for i := 1; i <= 2; i++ {
80+
const numFiles = 10
81+
82+
var fileNumbers []int
83+
for i := 0; i < numFiles; i++ {
84+
fileNumbers = append(fileNumbers, i)
85+
}
86+
rand.Shuffle(len(fileNumbers), func(i, j int) {
87+
fileNumbers[i], fileNumbers[j] = fileNumbers[j], fileNumbers[i]
88+
})
89+
90+
for _, i := range fileNumbers {
8091
f, err := osfs.Create(fmt.Sprintf("dir1/dir2/test%d.txt", i))
8192
if err != nil {
8293
t.Fatal(err)
@@ -89,25 +100,34 @@ func TestIOFSNativeDirEntryWhenPossible(t *testing.T) {
89100
t.Fatal(err)
90101
}
91102

92-
assertDirEntries := func(entries []fs.DirEntry) {
93-
if len(entries) != 2 {
94-
t.Fatalf("expected 2, got %d", len(entries))
103+
assertDirEntries := func(entries []fs.DirEntry, ordered bool) {
104+
if len(entries) != numFiles {
105+
t.Fatalf("expected %d, got %d", numFiles, len(entries))
95106
}
96-
for _, entry := range entries {
107+
for i, entry := range entries {
97108
if _, ok := entry.(dirEntry); ok {
98109
t.Fatal("DirEntry not native")
99110
}
111+
if ordered && entry.Name() != fmt.Sprintf("test%d.txt", i) {
112+
t.Fatalf("expected %s, got %s", fmt.Sprintf("test%d.txt", i), entry.Name())
113+
}
100114
}
101115
}
102116

103117
dirEntries, err := dir2.(fs.ReadDirFile).ReadDir(-1)
104118
if err != nil {
105119
t.Fatal(err)
106120
}
107-
assertDirEntries(dirEntries)
121+
assertDirEntries(dirEntries, false)
108122

109123
iofs := NewIOFS(osfs)
110124

125+
dirEntries, err = iofs.ReadDir("dir1/dir2")
126+
if err != nil {
127+
t.Fatal(err)
128+
}
129+
assertDirEntries(dirEntries, true)
130+
111131
fileCount := 0
112132
err = fs.WalkDir(iofs, "", func(path string, d fs.DirEntry, err error) error {
113133
if err != nil {
@@ -130,8 +150,8 @@ func TestIOFSNativeDirEntryWhenPossible(t *testing.T) {
130150
t.Fatal(err)
131151
}
132152

133-
if fileCount != 2 {
134-
t.Fatalf("expected 2, got %d", fileCount)
153+
if fileCount != numFiles {
154+
t.Fatalf("expected %d, got %d", numFiles, fileCount)
135155
}
136156

137157
}

ioutil.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func WriteFile(fs Fs, filename string, data []byte, perm os.FileMode) error {
141141
// We generate random temporary file names so that there's a good
142142
// chance the file doesn't exist yet - keeps the number of tries in
143143
// TempFile to a minimum.
144-
var rand uint32
144+
var randNum uint32
145145
var randmu sync.Mutex
146146

147147
func reseed() uint32 {
@@ -150,12 +150,12 @@ func reseed() uint32 {
150150

151151
func nextRandom() string {
152152
randmu.Lock()
153-
r := rand
153+
r := randNum
154154
if r == 0 {
155155
r = reseed()
156156
}
157157
r = r*1664525 + 1013904223 // constants from Numerical Recipes
158-
rand = r
158+
randNum = r
159159
randmu.Unlock()
160160
return strconv.Itoa(int(1e9 + r%1e9))[1:]
161161
}
@@ -194,7 +194,7 @@ func TempFile(fs Fs, dir, pattern string) (f File, err error) {
194194
if os.IsExist(err) {
195195
if nconflict++; nconflict > 10 {
196196
randmu.Lock()
197-
rand = reseed()
197+
randNum = reseed()
198198
randmu.Unlock()
199199
}
200200
continue
@@ -226,7 +226,7 @@ func TempDir(fs Fs, dir, prefix string) (name string, err error) {
226226
if os.IsExist(err) {
227227
if nconflict++; nconflict > 10 {
228228
randmu.Lock()
229-
rand = reseed()
229+
randNum = reseed()
230230
randmu.Unlock()
231231
}
232232
continue

0 commit comments

Comments
 (0)