1
+ package redis .clients .jedis .mcf ;
2
+
3
+ import eu .rekawek .toxiproxy .Proxy ;
4
+ import eu .rekawek .toxiproxy .ToxiproxyClient ;
5
+ import eu .rekawek .toxiproxy .model .ToxicDirection ;
6
+ import org .junit .jupiter .api .AfterAll ;
7
+ import org .junit .jupiter .api .BeforeAll ;
8
+ import org .junit .jupiter .api .BeforeEach ;
9
+ import org .junit .jupiter .api .Test ;
10
+ import org .junit .jupiter .api .Tag ;
11
+ import redis .clients .jedis .DefaultJedisClientConfig ;
12
+ import redis .clients .jedis .EndpointConfig ;
13
+ import redis .clients .jedis .HostAndPort ;
14
+ import redis .clients .jedis .HostAndPorts ;
15
+ import redis .clients .jedis .JedisClientConfig ;
16
+
17
+ import java .io .IOException ;
18
+
19
+ import static org .junit .jupiter .api .Assertions .*;
20
+
21
+ @ Tag ("failover" )
22
+ public class EchoStrategyIntegrationTest {
23
+
24
+ private static final EndpointConfig endpoint = HostAndPorts .getRedisEndpoint ("redis-failover-1" );
25
+ private static final HostAndPort proxyHostAndPort = endpoint .getHostAndPort ();
26
+ private static final ToxiproxyClient tp = new ToxiproxyClient ("localhost" , 8474 );
27
+ private static Proxy redisProxy ;
28
+
29
+ @ BeforeAll
30
+ public static void setupProxy () throws IOException {
31
+ if (tp .getProxyOrNull ("redis-health-test" ) != null ) {
32
+ tp .getProxy ("redis-health-test" ).delete ();
33
+ }
34
+ redisProxy = tp .createProxy ("redis-health-test" , "0.0.0.0:29379" , "redis-failover-1:9379" );
35
+ }
36
+
37
+ @ AfterAll
38
+ public static void cleanupProxy () throws IOException {
39
+ if (redisProxy != null ) {
40
+ redisProxy .delete ();
41
+ }
42
+ }
43
+
44
+ @ BeforeEach
45
+ public void resetProxy () throws IOException {
46
+ redisProxy .enable ();
47
+ redisProxy .toxics ().getAll ().forEach (toxic -> {
48
+ try {
49
+ toxic .remove ();
50
+ } catch (IOException e ) {
51
+ throw new RuntimeException (e );
52
+ }
53
+ });
54
+ }
55
+
56
+ @ Test
57
+ public void testEchoStrategyRecoversAfterDisconnect () throws Exception {
58
+ JedisClientConfig config = DefaultJedisClientConfig .builder ().socketTimeoutMillis (1000 )
59
+ .connectionTimeoutMillis (1000 ).build ();
60
+
61
+ try (EchoStrategy strategy = new EchoStrategy (proxyHostAndPort , config , 1000 , 500 , 1 )) {
62
+
63
+ // Initial health check should work
64
+ HealthStatus initialStatus = strategy .doHealthCheck (proxyHostAndPort );
65
+ assertEquals (HealthStatus .HEALTHY , initialStatus );
66
+
67
+ // Disable the proxy to simulate network failure
68
+ redisProxy .disable ();
69
+
70
+ // Health check should now fail - this will expose the bug
71
+ HealthStatus statusAfterDisable = strategy .doHealthCheck (proxyHostAndPort );
72
+ assertEquals (HealthStatus .UNHEALTHY , statusAfterDisable );
73
+
74
+ // Re-enable proxy
75
+ redisProxy .enable ();
76
+ // Health check should recover
77
+ HealthStatus statusAfterEnable = strategy .doHealthCheck (proxyHostAndPort );
78
+ assertEquals (HealthStatus .HEALTHY , statusAfterEnable );
79
+ }
80
+
81
+ }
82
+
83
+ @ Test
84
+ public void testEchoStrategyWithConnectionTimeout () throws Exception {
85
+ JedisClientConfig config = DefaultJedisClientConfig .builder ().socketTimeoutMillis (100 )
86
+ .connectionTimeoutMillis (100 ).build ();
87
+
88
+ try (EchoStrategy strategy = new EchoStrategy (proxyHostAndPort , config , 1000 , 300 , 1 )) {
89
+
90
+ // Initial health check should work
91
+ assertEquals (HealthStatus .HEALTHY , strategy .doHealthCheck (proxyHostAndPort ));
92
+
93
+ // Add latency toxic to simulate slow network
94
+ redisProxy .toxics ().latency ("slow-connection" , ToxicDirection .DOWNSTREAM , 1000 );
95
+
96
+ // Health check should timeout and return unhealthy
97
+ HealthStatus slowStatus = strategy .doHealthCheck (proxyHostAndPort );
98
+ assertEquals (HealthStatus .UNHEALTHY , slowStatus , "Health check should fail with high latency" );
99
+
100
+ // Remove toxic
101
+ redisProxy .toxics ().get ("slow-connection" ).remove ();
102
+
103
+ // Health check should recover
104
+ HealthStatus recoveredStatus = strategy .doHealthCheck (proxyHostAndPort );
105
+ assertEquals (HealthStatus .HEALTHY , recoveredStatus , "Health check should recover from high latency" );
106
+ }
107
+ }
108
+
109
+ @ Test
110
+ public void testConnectionDropDuringHealthCheck () throws Exception {
111
+ JedisClientConfig config = DefaultJedisClientConfig .builder ().socketTimeoutMillis (2000 ).build ();
112
+
113
+ try (EchoStrategy strategy = new EchoStrategy (proxyHostAndPort , config , 1000 , 1500 , 1 )) {
114
+
115
+ // Initial health check
116
+ assertEquals (HealthStatus .HEALTHY , strategy .doHealthCheck (proxyHostAndPort ));
117
+
118
+ // Simulate connection drop by limiting data transfer
119
+ redisProxy .toxics ().limitData ("connection-drop" , ToxicDirection .UPSTREAM , 10 );
120
+
121
+ // This should fail due to connection issues
122
+ HealthStatus droppedStatus = strategy .doHealthCheck (proxyHostAndPort );
123
+ assertEquals (HealthStatus .UNHEALTHY , droppedStatus );
124
+
125
+ // Remove toxic
126
+ redisProxy .toxics ().get ("connection-drop" ).remove ();
127
+
128
+ // Health check should recover
129
+ HealthStatus afterRecovery = strategy .doHealthCheck (proxyHostAndPort );
130
+ assertEquals (HealthStatus .HEALTHY , afterRecovery );
131
+ }
132
+ }
133
+ }
0 commit comments