test(analyze): race-check StoredDir stats against concurrent readers

This commit is contained in:
dualfroz committed 2026-08-26 16:28:38 +02:00
commit 606473d0fd
1 file changed
+58
+58
View File
@@ -0,0 +1,58 @@
package analyze
import (
"sync"
"testing"
"github.com/dundee/gdu/v5/internal/testdir"
"github.com/dundee/gdu/v5/pkg/fs"
"github.com/stretchr/testify/assert"
)
// TestStoredDirUpdateStatsLockedAgainstReaders recomputes a StoredDir's stats
// while another goroutine reads them through the synchronized scalar accessors
// (GetSize, GetUsage, GetFlag, GetMtime, GetItemCount). Those readers take the
// embedded Dir mutex, so updateStats has to write the same fields under that
// mutex. Run with -race: without the locking the writes in updateStats race the
// reads here.
func TestStoredDirUpdateStatsLockedAgainstReaders(t *testing.T) {
fin := testdir.CreateTestDir()
defer fin()
a := CreateStoredAnalyzer("/tmp/badger")
dir := a.AnalyzeDir(
"test_dir", func(_, _ string) bool { return false }, func(_ string) bool { return false },
).(*StoredDir)
a.GetDone().Wait()
const rounds = 200
stop := make(chan struct{})
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-stop:
return
default:
}
_ = dir.GetSize()
_ = dir.GetUsage()
_ = dir.GetFlag()
_ = dir.GetMtime()
_ = dir.GetItemCount()
}
}()
for range rounds {
dir.UpdateStats(make(fs.HardLinkedItems))
}
close(stop)
wg.Wait()
// stats stay correct after the concurrent recomputation
assert.Equal(t, int64(7+4096*3), dir.GetSize())
assert.Equal(t, int64(5), dir.GetItemCount())
}