From 18c27508f67d0572223c50a572fce9e675a5a049 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Thu, 22 Oct 2026 03:38:32 -0700 Subject: [PATCH] fuse integration: require a real mount before running tests Setup creates the mount point before weed mount starts, so statting and listing it succeeded on the plain directory and tests ran against local disk whenever the mount was slow or died. waitForMount now waits until the mount point's device id differs from its parent's. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- test/fuse_integration/framework.go | 11 ++++++++--- test/fuse_integration/mounted_unix.go | 14 ++++++++++++++ test/fuse_integration/mounted_unsupported.go | 10 ++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 test/fuse_integration/mounted_unix.go create mode 100644 test/fuse_integration/mounted_unsupported.go diff --git a/test/fuse_integration/framework.go b/test/fuse_integration/framework.go index 1a394fb595..3a4490a1df 100644 --- a/test/fuse_integration/framework.go +++ b/test/fuse_integration/framework.go @@ -376,11 +376,16 @@ func (f *FuseTestFramework) waitForService(addr string, timeout time.Duration) e // waitForMount waits for the FUSE mount to be ready func (f *FuseTestFramework) waitForMount(timeout time.Duration) error { + // The mount point is created before weed mount starts, so Stat/ReadDir + // alone succeed on the plain directory. The device id only differs from + // its parent's once a filesystem is actually mounted on it. + parentDev, err := deviceID(filepath.Dir(f.mountPoint)) + if err != nil { + return fmt.Errorf("stat mount parent: %w", err) + } deadline := time.Now().Add(timeout) for time.Now().Before(deadline) { - // Check if mount point is accessible - if _, err := os.Stat(f.mountPoint); err == nil { - // Try to list directory + if dev, err := deviceID(f.mountPoint); err == nil && dev != parentDev { if _, err := os.ReadDir(f.mountPoint); err == nil { return nil } diff --git a/test/fuse_integration/mounted_unix.go b/test/fuse_integration/mounted_unix.go new file mode 100644 index 0000000000..3e3fd0877d --- /dev/null +++ b/test/fuse_integration/mounted_unix.go @@ -0,0 +1,14 @@ +//go:build unix + +package fuse + +import "syscall" + +// deviceID returns the device ID of the filesystem containing path. +func deviceID(path string) (uint64, error) { + var st syscall.Stat_t + if err := syscall.Stat(path, &st); err != nil { + return 0, err + } + return uint64(st.Dev), nil +} diff --git a/test/fuse_integration/mounted_unsupported.go b/test/fuse_integration/mounted_unsupported.go new file mode 100644 index 0000000000..b59a080d5d --- /dev/null +++ b/test/fuse_integration/mounted_unsupported.go @@ -0,0 +1,10 @@ +//go:build !unix + +package fuse + +// FUSE mounts are unix-only: reporting one device keeps waitForMount from +// mistaking the plain pre-mount directory for a live mount on platforms +// where a mount can never appear. +func deviceID(path string) (uint64, error) { + return 0, nil +}