test(analyze): race-check StoredDir stats against concurrent readers
This commit is contained in:
commit
606473d0fd
1 file changed
+58
@@ -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())
|
||||
}
|
||||
Reference in new issue
Block a user