vfs/disk: Harden pending-window test against empty-dir race

Empty-dir disk init closes initDone almost immediately, so
TestDiskTierSignalMixedPendingReady can observe DiskTierReady=0 then
a heartbeat that already saw ready. Register a per-root init hold so
the test can keep the pending window open without slowing production.

Link: #36
This commit is contained in:
ash
2026-09-08 15:16:59 +00:00
parent de43a71929
commit fe04fb9fbb
3 changed files with 108 additions and 4 deletions
+54
View File
@@ -662,3 +662,57 @@ func TestDiskFS_NewMkdirError(t *testing.T) {
t.Errorf("expected mkdir failure error for file-as-dir, got: %v", err)
}
}
// TestDiskFS_InitHoldBlocksOnlyRegisteredRoot covers the per-root init hold:
// Size() stays blocked while the hold is open, and a DiskFS on a different root
// does not wait on that hold.
func TestDiskFS_InitHoldBlocksOnlyRegisteredRoot(t *testing.T) {
td := t.TempDir()
hold := make(chan struct{})
var holdOnce sync.Once
closeHold := func() { holdOnce.Do(func() { close(hold) }) }
RegisterInitHold(td, hold)
t.Cleanup(func() {
closeHold()
ClearInitHold(td)
})
d, err := New(td, 10*1024*1024, nil)
if err != nil {
t.Fatal(err)
}
blocked := make(chan struct{})
go func() {
_ = d.Size()
close(blocked)
}()
select {
case <-blocked:
t.Fatal("Size returned while init hold still open")
case <-time.After(50 * time.Millisecond):
}
td2 := t.TempDir()
d2, err := New(td2, 10*1024*1024, nil)
if err != nil {
t.Fatal(err)
}
other := make(chan struct{})
go func() {
_ = d2.Size()
close(other)
}()
select {
case <-other:
case <-time.After(2 * time.Second):
t.Fatal("unrelated DiskFS Size hung; init hold leaked across roots")
}
closeHold()
select {
case <-blocked:
case <-time.After(2 * time.Second):
t.Fatal("Size did not return after init hold released")
}
}