Files
dundee-gdu/pkg/analyze/stored_race_test.go
T

59 lines
1.4 KiB
Go

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())
}