1- using System ;
21using System . Net ;
3- using System . Net . Sockets ;
42using System . Threading . Tasks ;
5- using StackExchange . Redis . Server ;
63using Xunit ;
7- using Xunit . Sdk ;
84
95namespace StackExchange . Redis . Tests ;
106
@@ -15,18 +11,6 @@ namespace StackExchange.Redis.Tests;
1511/// </summary>
1612public class MovedToSameEndpointTests ( ITestOutputHelper log )
1713{
18- /// <summary>
19- /// Gets a free port by temporarily binding to port 0 and retrieving the OS-assigned port.
20- /// </summary>
21- private static int GetFreePort ( )
22- {
23- var listener = new TcpListener ( IPAddress . Loopback , 0 ) ;
24- listener . Start ( ) ;
25- var port = ( ( IPEndPoint ) listener . LocalEndpoint ) . Port ;
26- listener . Stop ( ) ;
27- return port ;
28- }
29-
3014 /// <summary>
3115 /// Integration test: Verifies that when a MOVED error points to the same endpoint,
3216 /// the client reconnects and successfully retries the operation.
@@ -49,73 +33,67 @@ private static int GetFreePort()
4933 public async Task MovedToSameEndpoint_TriggersReconnectAndRetry_CommandSucceeds ( )
5034 {
5135 var keyName = "MovedToSameEndpoint_TriggersReconnectAndRetry_CommandSucceeds" ;
52- // Arrange: Get a free port to avoid conflicts when tests run in parallel
53- var port = GetFreePort ( ) ;
54- var listenEndpoint = new IPEndPoint ( IPAddress . Loopback , port ) ;
5536
56- var testServer = new MovedTestServer (
37+ var listenEndpoint = new IPEndPoint ( IPAddress . Loopback , 6382 ) ;
38+ using var testServer = new MovedTestServer (
5739 getEndpoint : ( ) => Format . ToString ( listenEndpoint ) ,
58- triggerKey : keyName ) ;
40+ triggerKey : keyName ,
41+ log : log ) ;
5942
60- var socketServer = new RespSocketServer ( testServer ) ;
43+ testServer . SetActualEndpoint ( listenEndpoint ) ;
6144
62- try
63- {
64- // Start listening on the free port
65- socketServer . Listen ( listenEndpoint ) ;
66- testServer . SetActualEndpoint ( listenEndpoint ) ;
45+ // Wait a moment for the server to fully start
46+ await Task . Delay ( 100 ) ;
6747
68- // Wait a moment for the server to fully start
69- await Task . Delay ( 100 ) ;
48+ // Act: Connect to the test server
49+ var config = new ConfigurationOptions
50+ {
51+ EndPoints = { listenEndpoint } ,
52+ ConnectTimeout = 10000 ,
53+ SyncTimeout = 5000 ,
54+ AsyncTimeout = 5000 ,
55+ AllowAdmin = true ,
56+ Tunnel = testServer . Tunnel ,
57+ } ;
7058
71- // Act: Connect to the test server
72- var config = new ConfigurationOptions
73- {
74- EndPoints = { listenEndpoint } ,
75- ConnectTimeout = 10000 ,
76- SyncTimeout = 5000 ,
77- AsyncTimeout = 5000 ,
78- AllowAdmin = true ,
79- } ;
59+ await using var conn = await ConnectionMultiplexer . ConnectAsync ( config ) ;
60+ // Ping the server to ensure it's responsive
61+ var server = conn . GetServer ( listenEndpoint ) ;
62+ log ? . WriteLine ( ( await server . InfoRawAsync ( ) ) ?? "" ) ;
63+ var id = await server . ExecuteAsync ( "client" , "id" ) ;
64+ log ? . WriteLine ( $ "client id: { id } ") ;
8065
81- await using var conn = await ConnectionMultiplexer . ConnectAsync ( config ) ;
82- // Ping the server to ensure it's responsive
83- var server = conn . GetServer ( listenEndpoint ) ;
84- log ? . WriteLine ( $ "info: { await server . InfoRawAsync ( ) } ") ;
85- await server . PingAsync ( ) ;
86- // Verify server is detected as cluster mode
87- Assert . Equal ( ServerType . Cluster , server . ServerType ) ;
88- var db = conn . GetDatabase ( ) ;
66+ await server . PingAsync ( ) ;
67+ // Verify server is detected as cluster mode
68+ Assert . Equal ( ServerType . Cluster , server . ServerType ) ;
69+ var db = conn . GetDatabase ( ) ;
8970
90- // Record baseline counters after initial connection
91- var initialSetCmdCount = testServer . SetCmdCount ;
92- var initialMovedResponseCount = testServer . MovedResponseCount ;
93- var initialConnectionCount = testServer . ConnectionCount ;
94- // Execute SET command: This should receive MOVED → reconnect → retry → succeed
95- var setResult = await db . StringSetAsync ( keyName , "testvalue" ) ;
71+ // Record baseline counters after initial connection
72+ var initialSetCmdCount = testServer . SetCmdCount ;
73+ var initialMovedResponseCount = testServer . MovedResponseCount ;
74+ var initialConnectionCount = testServer . TotalClientCount ;
75+ // Execute SET command: This should receive MOVED → reconnect → retry → succeed
76+ var setResult = await db . StringSetAsync ( keyName , "testvalue" ) ;
9677
97- // Assert: Verify SET command succeeded
98- Assert . True ( setResult , "SET command should return true (OK)" ) ;
78+ // Assert: Verify SET command succeeded
79+ Assert . True ( setResult , "SET command should return true (OK)" ) ;
9980
100- // Verify the value was actually stored (proving retry succeeded)
101- var retrievedValue = await db . StringGetAsync ( keyName ) ;
102- Assert . Equal ( "testvalue" , ( string ? ) retrievedValue ) ;
81+ // Verify the value was actually stored (proving retry succeeded)
82+ var retrievedValue = await db . StringGetAsync ( keyName ) ;
83+ Assert . Equal ( "testvalue" , ( string ? ) retrievedValue ) ;
10384
104- // Verify SET command was executed twice: once with MOVED response, once successfully
105- var expectedSetCmdCount = initialSetCmdCount + 2 ;
106- Assert . Equal ( expectedSetCmdCount , testServer . SetCmdCount ) ;
85+ // Verify SET command was executed twice: once with MOVED response, once successfully
86+ var expectedSetCmdCount = initialSetCmdCount + 2 ;
87+ Assert . Equal ( expectedSetCmdCount , testServer . SetCmdCount ) ;
10788
108- // Verify MOVED response was returned exactly once
109- var expectedMovedResponseCount = initialMovedResponseCount + 1 ;
110- Assert . Equal ( expectedMovedResponseCount , testServer . MovedResponseCount ) ;
89+ // Verify MOVED response was returned exactly once
90+ var expectedMovedResponseCount = initialMovedResponseCount + 1 ;
91+ Assert . Equal ( expectedMovedResponseCount , testServer . MovedResponseCount ) ;
11192
112- // Verify reconnection occurred: connection count should have increased by 1
113- var expectedConnectionCount = initialConnectionCount + 1 ;
114- Assert . Equal ( expectedConnectionCount , testServer . ConnectionCount ) ;
115- }
116- finally
117- {
118- socketServer ? . Dispose ( ) ;
119- }
93+ // Verify reconnection occurred: connection count should have increased by 1
94+ var expectedConnectionCount = initialConnectionCount + 1 ;
95+ Assert . Equal ( expectedConnectionCount , testServer . TotalClientCount ) ;
96+ id = await server . ExecuteAsync ( "client" , "id" ) ;
97+ log ? . WriteLine ( $ "client id: { id } ") ;
12098 }
12199}
0 commit comments