aboutsummaryrefslogtreecommitdiff
path: root/weed/wdclient/masterclient_test.go
diff options
context:
space:
mode:
authorChris Lu <chrislusf@users.noreply.github.com>2025-12-13 12:10:15 -0800
committerGitHub <noreply@github.com>2025-12-13 12:10:15 -0800
commitd80d8be01208ffe82861b8aa50d4baf599fdfa02 (patch)
treefa6cf7c55579356d4a73514c71e0ec167eb44c47 /weed/wdclient/masterclient_test.go
parent36b8b2147b55068f65f6c4cacc5645bc3453f173 (diff)
downloadseaweedfs-d80d8be01208ffe82861b8aa50d4baf599fdfa02.tar.xz
seaweedfs-d80d8be01208ffe82861b8aa50d4baf599fdfa02.zip
fix(s3): start KeepConnectedToMaster for filer discovery with filerGroup (#7732)
Fixes #7721 When S3 server is configured with a filerGroup, it creates a MasterClient to enable dynamic filer discovery. However, the KeepConnectedToMaster() background goroutine was never started, causing GetMaster() to block indefinitely in WaitUntilConnected(). This resulted in the log message: WaitUntilConnected still waiting for master connection (attempt N)... being logged repeatedly every ~20 seconds. The fix adds the missing 'go masterClient.KeepConnectedToMaster(ctx)' call to properly establish the connection to master servers. Also adds unit tests to verify WaitUntilConnected respects context cancellation.
Diffstat (limited to 'weed/wdclient/masterclient_test.go')
-rw-r--r--weed/wdclient/masterclient_test.go104
1 files changed, 104 insertions, 0 deletions
diff --git a/weed/wdclient/masterclient_test.go b/weed/wdclient/masterclient_test.go
new file mode 100644
index 000000000..d88de40c1
--- /dev/null
+++ b/weed/wdclient/masterclient_test.go
@@ -0,0 +1,104 @@
+package wdclient
+
+import (
+ "context"
+ "testing"
+ "time"
+
+ "github.com/seaweedfs/seaweedfs/weed/pb"
+ "google.golang.org/grpc"
+)
+
+// TestWaitUntilConnectedWithoutKeepConnected verifies that WaitUntilConnected
+// respects context cancellation when KeepConnectedToMaster is not running.
+// This tests the fix for https://github.com/seaweedfs/seaweedfs/issues/7721
+func TestWaitUntilConnectedWithoutKeepConnected(t *testing.T) {
+ mc := NewMasterClient(grpc.EmptyDialOption{}, "test-group", "test-client", "", "", "", pb.ServerDiscovery{})
+
+ // Without KeepConnectedToMaster running, WaitUntilConnected should
+ // respect context cancellation and not block forever
+ ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
+ defer cancel()
+
+ start := time.Now()
+ mc.WaitUntilConnected(ctx)
+ elapsed := time.Since(start)
+
+ // Should have returned due to context timeout, not blocked forever
+ if elapsed > 200*time.Millisecond {
+ t.Errorf("WaitUntilConnected blocked for %v, expected to return on context timeout", elapsed)
+ }
+
+ // GetMaster should return empty since we never connected
+ master := mc.getCurrentMaster()
+ if master != "" {
+ t.Errorf("Expected empty master, got %s", master)
+ }
+}
+
+// TestWaitUntilConnectedReturnsImmediatelyWhenConnected verifies that
+// WaitUntilConnected returns immediately when a master is already set.
+func TestWaitUntilConnectedReturnsImmediatelyWhenConnected(t *testing.T) {
+ mc := NewMasterClient(grpc.EmptyDialOption{}, "test-group", "test-client", "", "", "", pb.ServerDiscovery{})
+
+ // Simulate that KeepConnectedToMaster has already established a connection
+ mc.setCurrentMaster("localhost:9333")
+
+ ctx := context.Background()
+ start := time.Now()
+ mc.WaitUntilConnected(ctx)
+ elapsed := time.Since(start)
+
+ // Should return almost immediately (< 10ms)
+ if elapsed > 10*time.Millisecond {
+ t.Errorf("WaitUntilConnected took %v when master was already set, expected immediate return", elapsed)
+ }
+
+ // Verify master is returned
+ master := mc.getCurrentMaster()
+ if master != "localhost:9333" {
+ t.Errorf("Expected master localhost:9333, got %s", master)
+ }
+}
+
+// TestGetMasterRespectsContextCancellation verifies that GetMaster
+// respects context cancellation and doesn't block forever.
+func TestGetMasterRespectsContextCancellation(t *testing.T) {
+ mc := NewMasterClient(grpc.EmptyDialOption{}, "test-group", "test-client", "", "", "", pb.ServerDiscovery{})
+
+ // GetMaster calls WaitUntilConnected internally
+ ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
+ defer cancel()
+
+ start := time.Now()
+ master := mc.GetMaster(ctx)
+ elapsed := time.Since(start)
+
+ // Should return on context timeout
+ if elapsed > 200*time.Millisecond {
+ t.Errorf("GetMaster blocked for %v, expected to return on context timeout", elapsed)
+ }
+
+ // Master should be empty since we never connected
+ if master != "" {
+ t.Errorf("Expected empty master when not connected, got %s", master)
+ }
+}
+
+// TestMasterClientFilerGroupLogging verifies the FilerGroup is properly set
+// and would be logged correctly (regression test for issue #7721 log message format)
+func TestMasterClientFilerGroupLogging(t *testing.T) {
+ filerGroup := "filer_1"
+ clientType := "s3"
+
+ mc := NewMasterClient(grpc.EmptyDialOption{}, filerGroup, clientType, "", "", "", pb.ServerDiscovery{})
+
+ if mc.FilerGroup != filerGroup {
+ t.Errorf("Expected FilerGroup %s, got %s", filerGroup, mc.FilerGroup)
+ }
+
+ if mc.clientType != clientType {
+ t.Errorf("Expected clientType %s, got %s", clientType, mc.clientType)
+ }
+}
+