From cb882ced468b7c658db847ef1820304ea346bb40 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 22 Apr 2026 10:33:11 -0700 Subject: [PATCH] fix(test): retry ENOENT in fcntl lock subprocess helper TestPosixFileLocking/FcntlReleaseOnClose was flaky because the subprocess spawned by startLockHolder occasionally saw ENOENT when opening a file the parent had just created on the FUSE mount. Retry on ENOENT (matching the existing openWithRetry pattern used in testConcurrentLockContention) so the subprocess waits for the mount's dentry state to propagate before reporting the lock acquire as failed. --- test/fuse_integration/posix_file_lock_test.go | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/test/fuse_integration/posix_file_lock_test.go b/test/fuse_integration/posix_file_lock_test.go index 1712aa4b2..e96c0c0f9 100644 --- a/test/fuse_integration/posix_file_lock_test.go +++ b/test/fuse_integration/posix_file_lock_test.go @@ -82,9 +82,25 @@ func TestFcntlLockHelper(t *testing.T) { start, _ := strconv.ParseInt(os.Getenv("LOCK_START"), 10, 64) length, _ := strconv.ParseInt(os.Getenv("LOCK_LEN"), 10, 64) - f, err := os.OpenFile(filePath, os.O_RDWR, 0) - if err != nil { - fmt.Fprintf(os.Stderr, "open: %v\n", err) + // The parent test process created the file on the FUSE mount just before + // spawning this subprocess. A fresh lookup from a different process can + // briefly return ENOENT while the mount's dentry state propagates, so + // retry on ENOENT before giving up. + var f *os.File + var openErr error + for attempt := 0; attempt < 40; attempt++ { + f, openErr = os.OpenFile(filePath, os.O_RDWR, 0) + if openErr == nil { + break + } + if !errors.Is(openErr, os.ErrNotExist) && !errors.Is(openErr, syscall.ENOENT) { + break + } + _, _ = os.ReadDir(filepath.Dir(filePath)) + time.Sleep(50 * time.Millisecond) + } + if openErr != nil { + fmt.Fprintf(os.Stderr, "open: %v\n", openErr) os.Exit(1) } defer f.Close()