Compare commits

...
Author SHA1 Message Date
Chris Lu 1fe294fd44 fix(fuse-tests): drop glog globals from TestWriteBufferCap mount options
-logtostderr and -v are glog globals parsed before the subcommand; weed
mount's flag set rejects them, so the mount process exited with a usage
error and the test silently ran against the local disk (masked until
waitForMount started verifying a real mount). glog already writes to
stderr here by default, so the options were also redundant.
2026-07-02 15:47:41 -07:00
Chris Lu 57246c345b fix(fuse-tests): don't declare the FUSE mount ready before it is mounted
waitForMount probed the mount point with stat+ReadDir, which a bare local
directory also passes, so Setup could return before the weed mount process
finished mounting. Tests then wrote to the local disk underneath the mount
point; when the mount activated it shadowed those files, producing the
intermittent TestConcurrentFileOperations/ConcurrentReadWrite ENOENT with
an empty ReadDir. Require the mount point's device ID to differ from its
parent's before reporting ready.
2026-07-02 13:27:07 -07:00
2 changed files with 22 additions and 9 deletions
+19 -2
View File
@@ -333,11 +333,19 @@ func (f *FuseTestFramework) waitForService(addr string, timeout time.Duration) e
return fmt.Errorf("service at %s not ready within timeout", addr)
}
// waitForMount waits for the FUSE mount to be ready
// waitForMount waits for the FUSE mount to be ready. A stat/ReadDir probe
// alone is not enough: the bare mount point directory passes both before the
// mount process finishes starting, letting tests race ahead and write to the
// local disk underneath the mount. The mount point's device ID differing from
// its parent's confirms a filesystem is actually mounted there.
func (f *FuseTestFramework) waitForMount(timeout time.Duration) error {
parentDev, err := deviceID(filepath.Dir(f.mountPoint))
if err != nil {
return fmt.Errorf("stat mount point parent: %v", err)
}
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
if _, err := os.Stat(f.mountPoint); err == nil {
if dev, err := deviceID(f.mountPoint); err == nil && dev != parentDev {
if _, err := os.ReadDir(f.mountPoint); err == nil {
return nil
}
@@ -347,6 +355,15 @@ func (f *FuseTestFramework) waitForMount(timeout time.Duration) error {
return fmt.Errorf("mount point not ready within timeout")
}
// 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
}
// findWeedBinary locates the weed binary.
func findWeedBinary() string {
if p, err := exec.LookPath("weed"); err == nil {
@@ -88,13 +88,9 @@ func writeBufferCapConfig(debugPort int) *TestConfig {
"-writeBufferSizeMB=16",
"-debug=true",
fmt.Sprintf("-debug.port=%d", debugPort),
// Route glog to stderr so the framework's process log
// capture actually contains something — by default weed
// sends glog to /tmp/weed.* files which the CI artifact
// upload step never sees. Critical for diagnosing
// upload/saveToStorage errors on Linux runs.
"-logtostderr=true",
"-v=2",
// NOTE: glog flags (-logtostderr, -v) are globals parsed
// before the subcommand; passing them here makes weed
// mount exit with a usage error before ever mounting.
},
SkipCleanup: false,
}