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