18
18
const { expect } = require ( 'chai' ) ;
19
19
const RC = require ( '../../RC' ) ;
20
20
const TestUtil = require ( '../../../TestUtil' ) ;
21
+ const sinon = require ( 'sinon' ) ;
22
+ const sandbox = sinon . createSandbox ( ) ;
23
+ const { ConnectionManager } = require ( '../../../../lib/network/ConnectionManager' ) ;
21
24
22
25
/**
23
26
* Basic tests for reconnection to cluster scenarios.
@@ -26,28 +29,6 @@ describe('ClientReconnectTest', function () {
26
29
let cluster ;
27
30
let client ;
28
31
29
- /**
30
- * Waits for disconnection. getMap(), map.put() messages are not retryable. If terminateMember does not
31
- * close the client connection immediately it is possible for the client to realize that later when map.put
32
- * or getMap invocation started. In that case, the connection will be closed with TargetDisconnectedError.
33
- * Because these client messages are not retryable, the invocation will be rejected with an error, leading
34
- * to flaky tests. To avoid that, this function will wait for the connections count to be zero.
35
- */
36
- const waitForDisconnection = async ( client ) => {
37
- let getConnectionsFn ;
38
- if ( TestUtil . isClientVersionAtLeast ( '4.2' ) ) {
39
- const clientRegistry = client . connectionRegistry ;
40
- getConnectionsFn = clientRegistry . getConnections . bind ( clientRegistry ) ;
41
- } else {
42
- const connManager = client . getConnectionManager ( ) ;
43
- getConnectionsFn = connManager . getActiveConnections . bind ( connManager ) ;
44
- }
45
-
46
- await TestUtil . assertTrueEventually ( async ( ) => {
47
- expect ( getConnectionsFn ( ) ) . to . be . empty ;
48
- } ) ;
49
- } ;
50
-
51
32
const testFactory = new TestUtil . TestFactory ( ) ;
52
33
53
34
beforeEach ( function ( ) {
@@ -59,6 +40,37 @@ describe('ClientReconnectTest', function () {
59
40
await testFactory . shutdownAll ( ) ;
60
41
} ) ;
61
42
43
+ it ( 'should send the client state to the cluster after reconnections, ' +
44
+ + 'regardless it is connected back to possibly the same cluster with the same id or not.' , async function ( ) {
45
+ const fakeInitializeClientOnCluster = sandbox . replace (
46
+ ConnectionManager . prototype ,
47
+ 'initializeClientOnCluster' ,
48
+ sandbox . fake ( ConnectionManager . prototype . initializeClientOnCluster )
49
+ ) ;
50
+ cluster = await testFactory . createClusterForSerialTests ( ) ;
51
+ const member = await RC . startMember ( cluster . id ) ;
52
+ client = await testFactory . newHazelcastClientForSerialTests ( {
53
+ clusterName : cluster . id ,
54
+ properties : {
55
+ 'hazelcast.client.heartbeat.interval' : 1000 ,
56
+ 'hazelcast.client.heartbeat.timeout' : 3000
57
+ }
58
+ } ) ;
59
+ await RC . terminateMember ( cluster . id , member . uuid ) ;
60
+ await TestUtil . waitForConnectionCount ( client , 0 ) ;
61
+ await RC . startMember ( cluster . id ) ;
62
+ await TestUtil . waitForConnectionCount ( client , 1 ) ;
63
+ fakeInitializeClientOnCluster . callCount . should . be . eq ( 1 ) ;
64
+ } ) ;
65
+
66
+ /**
67
+ * getMap(), map.put() messages are not retryable. If terminateMember does not
68
+ * close the client connection immediately it is possible for the client to realize that later when map.put
69
+ * or getMap invocation started. In that case, the connection will be closed with TargetDisconnectedError.
70
+ * Because these client messages are not retryable, the invocation will be rejected with an error, leading
71
+ * to flaky tests. To avoid that, we use the "TestUtil.waitForConnectionCount" function
72
+ * to wait for disconnection in the tests below.
73
+ */
62
74
it ( 'member restarts, while map.put in progress' , async function ( ) {
63
75
cluster = await testFactory . createClusterForSerialTests ( ) ;
64
76
const member = await RC . startMember ( cluster . id ) ;
@@ -72,7 +84,7 @@ describe('ClientReconnectTest', function () {
72
84
const map = await client . getMap ( 'test' ) ;
73
85
74
86
await RC . terminateMember ( cluster . id , member . uuid ) ;
75
- await waitForDisconnection ( client ) ;
87
+ await TestUtil . waitForConnectionCount ( client , 0 ) ;
76
88
await RC . startMember ( cluster . id ) ;
77
89
78
90
await map . put ( 'testkey' , 'testvalue' ) ;
@@ -95,7 +107,7 @@ describe('ClientReconnectTest', function () {
95
107
} ) ;
96
108
const map = await client . getMap ( 'test' ) ;
97
109
await RC . terminateMember ( cluster . id , member . uuid ) ;
98
- await waitForDisconnection ( client ) ;
110
+ await TestUtil . waitForConnectionCount ( client , 0 ) ;
99
111
100
112
const promise = map . put ( 'testkey' , 'testvalue' ) . then ( ( ) => {
101
113
return map . get ( 'testkey' ) ;
@@ -119,7 +131,7 @@ describe('ClientReconnectTest', function () {
119
131
}
120
132
} ) ;
121
133
await RC . terminateMember ( cluster . id , member . uuid ) ;
122
- await waitForDisconnection ( client ) ;
134
+ await TestUtil . waitForConnectionCount ( client , 0 ) ;
123
135
124
136
let map ;
125
137
0 commit comments