list: fix ext sort error sometimes being ignored at the end of a listing

Sorter.Send selects on both the output and error channels of the ext
sort. If the ext sort failed it closes both, so the select could pick
the closed output channel and return without the error. This was seen
as a flaky TestSorterExtTempFileError under the race detector.
This commit is contained in:
Nick Craig-Wood committed 2026-10-17 15:48:14 +01:00
1 parent 3ae50732b5
commit 7436d05e36
2 files changed
+31

No files matched your search

+5
View File
@@ -305,6 +305,11 @@ func (ls *Sorter) Send() (err error) {
}
}
}
// The select may see outputChan closed before reading the
// error the sorter sent on errChan
if err := <-ls.errChan; err != nil {
return err
}
err = list.Flush()
if err != nil {
return err
+26
View File
@@ -3,6 +3,7 @@ package list
import (
"cmp"
"context"
"errors"
"fmt"
"os"
"path/filepath"
@@ -285,6 +286,31 @@ func TestSorterExtTempFileError(t *testing.T) {
require.Error(t, err)
}
// Test that Send returns the error from the ext sort when the ext
// sort closes its output and error channels before Send reads them.
func TestSorterExtSendError(t *testing.T) {
ctx := context.Background()
callback := func(entries fs.DirEntries) error {
return nil
}
// select picks randomly between ready channels so try many times
for range 100 {
ls, err := NewSorter(ctx, nil, callback, nil)
require.NoError(t, err)
outputChan := make(chan string)
close(outputChan)
errChan := make(chan error, 1)
errChan <- errors.New("sort failed")
close(errChan)
ls.extSort = true
ls.inputChan = make(chan string)
ls.outputChan = outputChan
ls.errChan = errChan
require.EqualError(t, ls.Send(), "sort failed")
ls.CleanUp()
}
}
// benchFs implements enough of the fs.Fs interface for Sorter
type benchFs struct{}