20
20
import DirectConnectionProvider from '../../src/connection-provider/connection-provider-direct'
21
21
import { Pool } from '../../src/pool'
22
22
import { Connection , DelegateConnection } from '../../src/connection'
23
- import { internal , newError } from 'neo4j-driver-core'
23
+ import { internal , newError , ServerInfo } from 'neo4j-driver-core'
24
24
25
25
const {
26
26
serverAddress : { ServerAddress } ,
@@ -139,6 +139,180 @@ it('should not change error when TokenExpired happens', async () => {
139
139
expect ( error ) . toBe ( expectedError )
140
140
} )
141
141
142
+ describe ( '.verifyConnectivityAndGetServerInfo()' , ( ) => {
143
+ describe ( 'when connection is available in the pool' , ( ) => {
144
+ it ( 'should return the server info' , async ( ) => {
145
+ const { connectionProvider, server, protocolVersion } = setup ( )
146
+
147
+ const serverInfo = await connectionProvider . verifyConnectivityAndGetServerInfo ( )
148
+
149
+ expect ( serverInfo ) . toEqual ( new ServerInfo ( server , protocolVersion ) )
150
+ } )
151
+
152
+ it ( 'should reset and flush the connection' , async ( ) => {
153
+ const { connectionProvider, resetAndFlush } = setup ( )
154
+
155
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
156
+
157
+ expect ( resetAndFlush ) . toBeCalledTimes ( 1 )
158
+ } )
159
+
160
+ it ( 'should release the connection' , async ( ) => {
161
+ const { connectionProvider, seenConnections } = setup ( )
162
+
163
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
164
+
165
+ expect ( seenConnections [ 0 ] . _release ) . toHaveBeenCalledTimes ( 1 )
166
+ } )
167
+
168
+ it ( 'should resetAndFlush and then release the connection' , async ( ) => {
169
+ const { connectionProvider, seenConnections, resetAndFlush } = setup ( )
170
+
171
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
172
+
173
+ expect ( seenConnections [ 0 ] . _release . mock . invocationCallOrder [ 0 ] )
174
+ . toBeGreaterThan ( resetAndFlush . mock . invocationCallOrder [ 0 ] )
175
+ } )
176
+
177
+ describe ( 'when reset and flush fails' , ( ) => {
178
+ it ( 'should fails with the reset and flush error' , async ( ) => {
179
+ const error = newError ( 'Error' )
180
+ const { connectionProvider, resetAndFlush } = setup ( )
181
+
182
+ resetAndFlush . mockRejectedValue ( error )
183
+
184
+ try {
185
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
186
+ expect ( ) . toBe ( 'Not reached' )
187
+ } catch ( e ) {
188
+ expect ( e ) . toBe ( error )
189
+ }
190
+ } )
191
+
192
+ it ( 'should release the connection' , async ( ) => {
193
+ const error = newError ( 'Error' )
194
+ const { connectionProvider, resetAndFlush, seenConnections } = setup ( )
195
+
196
+ resetAndFlush . mockRejectedValue ( error )
197
+
198
+ try {
199
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
200
+ } catch ( e ) {
201
+ } finally {
202
+ expect ( seenConnections [ 0 ] . _release ) . toHaveBeenCalledTimes ( 1 )
203
+ }
204
+ } )
205
+
206
+ describe ( 'and release fails' , ( ) => {
207
+ it ( 'should fails with the release error' , async ( ) => {
208
+ const error = newError ( 'Error' )
209
+ const releaseError = newError ( 'release errror' )
210
+
211
+ const { connectionProvider, resetAndFlush } = setup (
212
+ {
213
+ releaseMock : ( ) => Promise . reject ( releaseError )
214
+ } )
215
+
216
+ resetAndFlush . mockRejectedValue ( error )
217
+
218
+ try {
219
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
220
+ expect ( ) . toBe ( 'Not reached' )
221
+ } catch ( e ) {
222
+ expect ( e ) . toBe ( releaseError )
223
+ }
224
+ } )
225
+ } )
226
+ } )
227
+
228
+ describe ( 'when release fails' , ( ) => {
229
+ it ( 'should fails with the release error' , async ( ) => {
230
+ const error = newError ( 'Error' )
231
+
232
+ const { connectionProvider } = setup (
233
+ {
234
+ releaseMock : ( ) => Promise . reject ( error )
235
+ } )
236
+
237
+ try {
238
+ await connectionProvider . verifyConnectivityAndGetServerInfo ( )
239
+ expect ( ) . toBe ( 'Not reached' )
240
+ } catch ( e ) {
241
+ expect ( e ) . toBe ( error )
242
+ }
243
+ } )
244
+ } )
245
+
246
+ function setup ( { releaseMock } = { } ) {
247
+ const protocolVersion = 4.4
248
+ const resetAndFlush = jest . fn ( ( ) => Promise . resolve ( ) )
249
+ const server = { address : 'localhost:123' , version : 'neo4j/1234' }
250
+ const seenConnections = [ ]
251
+ const create = ( address , release ) => {
252
+ const connection = new FakeConnection ( address , release , server )
253
+ connection . protocol = ( ) => {
254
+ return { version : protocolVersion }
255
+ }
256
+ connection . resetAndFlush = resetAndFlush
257
+ if ( releaseMock ) {
258
+ connection . _release = releaseMock
259
+ }
260
+ seenConnections . push ( connection )
261
+ return connection
262
+ }
263
+ const address = ServerAddress . fromUrl ( 'localhost:123' )
264
+ const pool = newPool ( { create } )
265
+ const connectionProvider = newDirectConnectionProvider ( address , pool )
266
+ return {
267
+ connectionProvider,
268
+ server,
269
+ protocolVersion,
270
+ resetAndFlush,
271
+ seenConnections
272
+ }
273
+ }
274
+ } )
275
+
276
+ describe ( 'when connection is not available in the pool' , ( ) => {
277
+ it ( 'should reject with acquisition timeout error' , async ( ) => {
278
+ const address = ServerAddress . fromUrl ( 'localhost:123' )
279
+ const pool = newPool ( {
280
+ config : {
281
+ acquisitionTimeout : 0 ,
282
+ }
283
+ } )
284
+
285
+ const connectionProvider = newDirectConnectionProvider ( address , pool )
286
+
287
+ try {
288
+ connectionProvider = await connectionProvider . verifyConnectivityAndGetServerInfo ( )
289
+ expect ( ) . toBe ( 'not reached' )
290
+ } catch ( e ) {
291
+ expect ( e ) . toBeDefined ( )
292
+ }
293
+ } )
294
+ } )
295
+
296
+ describe ( 'when connection it could not create the connection' , ( ) => {
297
+ it ( 'should reject with connection creation error' , async ( ) => {
298
+ const error = new Error ( 'Connection creation error' )
299
+ const address = ServerAddress . fromUrl ( 'localhost:123' )
300
+ const pool = newPool ( {
301
+ create : ( ) => { throw error }
302
+ } )
303
+
304
+ const connectionProvider = newDirectConnectionProvider ( address , pool )
305
+
306
+ try {
307
+ connectionProvider = await connectionProvider . verifyConnectivityAndGetServerInfo ( )
308
+ expect ( ) . toBe ( 'not reached' )
309
+ } catch ( e ) {
310
+ expect ( e ) . toBe ( error )
311
+ }
312
+ } )
313
+ } )
314
+ } )
315
+
142
316
function newDirectConnectionProvider ( address , pool ) {
143
317
const connectionProvider = new DirectConnectionProvider ( {
144
318
id : 0 ,
@@ -150,22 +324,34 @@ function newDirectConnectionProvider (address, pool) {
150
324
return connectionProvider
151
325
}
152
326
153
- function newPool ( ) {
327
+ function newPool ( { create, config } = { } ) {
328
+ const _create = ( address , release ) => {
329
+ if ( create ) {
330
+ return create ( address , release )
331
+ }
332
+ return new FakeConnection ( address , release )
333
+ }
154
334
return new Pool ( {
335
+ config,
155
336
create : ( address , release ) =>
156
- Promise . resolve ( new FakeConnection ( address , release ) )
337
+ Promise . resolve ( _create ( address , release ) ) ,
157
338
} )
158
339
}
159
340
160
341
class FakeConnection extends Connection {
161
- constructor ( address , release ) {
342
+ constructor ( address , release , server ) {
162
343
super ( null )
163
344
164
345
this . _address = address
165
- this . release = release
346
+ this . _release = jest . fn ( ( ) => release ( address , this ) )
347
+ this . _server = server
166
348
}
167
349
168
- get address ( ) {
350
+ get address ( ) {
169
351
return this . _address
170
352
}
353
+
354
+ get server ( ) {
355
+ return this . _server
356
+ }
171
357
}
0 commit comments