From 81e0859c122c9a827eab9487aea163387c476b77 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Fri, 23 Oct 2026 20:54:52 -0700 Subject: [PATCH] test(s3 remote cache): wait for the master to list the filer before shell commands (#12018) A fresh single-filer mini registers its filer only after the ~10s empty-membership confirm window, and weed shell locates the filer via the master's listing, so remote.configure sent right after the S3 health check races it. Ports the wait from the enterprise test to the OSS copy. --- .../remote_cache/remote_cache_evict_test.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/s3/remote_cache/remote_cache_evict_test.go b/test/s3/remote_cache/remote_cache_evict_test.go index cb44f1f3fb..8fab9c53b9 100644 --- a/test/s3/remote_cache/remote_cache_evict_test.go +++ b/test/s3/remote_cache/remote_cache_evict_test.go @@ -99,6 +99,27 @@ func shellOn(t *testing.T, masterPort, command string) string { return stripLogs(string(out)) } +// waitForFilerListed polls the master until it lists a filer. A fresh +// single-filer mini registers its filer only after an ~10 s empty-membership +// confirm, and weed shell finds the filer through that listing, so shell +// commands sent before it fail. +func waitForFilerListed(t *testing.T, masterPort string) { + t.Helper() + deadline := time.Now().Add(60 * time.Second) + for { + cmd := exec.Command(weedBinary, "shell", "-master=localhost:"+masterPort) + cmd.Stdin = strings.NewReader("cluster.ps\nexit\n") + out, err := cmd.CombinedOutput() + if err == nil && strings.Contains(string(out), "* filers ") && !strings.Contains(string(out), "* filers 0\n") { + return + } + if time.Now().After(deadline) { + t.Fatalf("master on %s lists no filer after 60s: %v\n%s", masterPort, err, out) + } + time.Sleep(time.Second) + } +} + func chunkCountOn(t *testing.T, masterPort, path string) string { meta := shellOn(t, masterPort, "fs.meta.cat "+path) idx := strings.LastIndex(meta, "chunks ") @@ -166,6 +187,7 @@ func TestRemoteCacheEvictUnderPressure(t *testing.T) { "-master.volumeSizeLimitMB=32", "-volume.max=2", "-filer.remoteCacheEvictThreshold=0.99") waitForHTTP(t, evictPrimaryS3) + waitForFilerListed(t, evictPrimaryMaster) remote := createS3Client(evictRemoteS3) _, err := remote.CreateBucket(&s3.CreateBucketInput{Bucket: aws.String(evictBucket)})