Skip to content

Commit 02cb649

Browse files
yuukiclaude
andcommitted
test: add comprehensive test for multiple concurrent client connections
- Add TestE2EMultipleConcurrentClients to verify server can handle multiple clients simultaneously - Fix race conditions by using individual ClientConfig instances per goroutine - Modernize loop syntax using 'for i := range numClients' - Remove dependency on global variable manipulation to prevent stdout conflicts - Test validates that 3 concurrent clients can connect and communicate with server successfully 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent e86322a commit 02cb649

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

e2e_test.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,3 +808,96 @@ func TestE2EAllProtocols(t *testing.T) {
808808
serverCancel()
809809
serverWg.Wait()
810810
}
811+
812+
// TestE2EMultipleConcurrentClients tests server handling multiple concurrent client connections
813+
func TestE2EMultipleConcurrentClients(t *testing.T) {
814+
port := findAvailablePort()
815+
addr := fmt.Sprintf("127.0.0.1:%d", port)
816+
817+
// Setup server
818+
originalServeAddrs := listenAddrs
819+
originalServeProtocol := serveProtocol
820+
defer func() {
821+
listenAddrs = originalServeAddrs
822+
serveProtocol = originalServeProtocol
823+
}()
824+
825+
listenAddrs = []string{addr}
826+
serveProtocol = "tcp"
827+
828+
// Start server
829+
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
830+
defer cancel()
831+
832+
var serverWg sync.WaitGroup
833+
serverWg.Add(1)
834+
835+
serverCtx, serverCancel := context.WithCancel(ctx)
836+
go func() {
837+
defer serverWg.Done()
838+
server := NewServer(ServerConfig{
839+
ListenAddrs: []string{addr},
840+
Protocol: "tcp",
841+
})
842+
if err := server.serveTCP(serverCtx); err != nil {
843+
t.Logf("Multiple clients server completed: %v", err)
844+
}
845+
}()
846+
847+
// Wait for server to start
848+
time.Sleep(200 * time.Millisecond)
849+
850+
// Verify server is listening
851+
conn, err := net.DialTimeout("tcp", addr, time.Second)
852+
if err != nil {
853+
serverCancel()
854+
t.Fatalf("Failed to connect to server: %v", err)
855+
}
856+
conn.Close()
857+
858+
// Setup multiple concurrent clients
859+
860+
numClients := 3
861+
var clientWg sync.WaitGroup
862+
clientWg.Add(numClients)
863+
clientErrors := make([]error, numClients)
864+
865+
// Start multiple clients concurrently
866+
for i := range numClients {
867+
go func(clientID int) {
868+
defer clientWg.Done()
869+
870+
// Create individual client config to avoid race conditions
871+
clientCtx, clientCancel := context.WithTimeout(ctx, 3*time.Second)
872+
defer clientCancel()
873+
874+
config := ClientConfig{
875+
Protocol: "tcp",
876+
ConnectFlavor: flavorPersistent,
877+
Connections: 2,
878+
ConnectRate: 10,
879+
Duration: 3 * time.Second,
880+
MessageBytes: 64,
881+
MergeResultsEachHost: false,
882+
JSONLines: false,
883+
}
884+
885+
client := NewClient(config)
886+
clientErrors[clientID] = client.ConnectToAddresses(clientCtx, []string{addr})
887+
}(i)
888+
}
889+
890+
// Wait for all clients to complete
891+
clientWg.Wait()
892+
893+
// Check if any client had errors
894+
for i, err := range clientErrors {
895+
if err != nil {
896+
t.Errorf("Client %d error: %v", i, err)
897+
}
898+
}
899+
900+
// Cleanup
901+
serverCancel()
902+
serverWg.Wait()
903+
}

0 commit comments

Comments
 (0)