2020import DirectConnectionProvider from '../../src/connection-provider/connection-provider-direct'
2121import { Pool } from '../../src/pool'
2222import { Connection , DelegateConnection } from '../../src/connection'
23- import { internal , newError } from 'neo4j-driver-core'
23+ import { internal , newError , ServerInfo } from 'neo4j-driver-core'
2424
2525const {
2626 serverAddress : { ServerAddress } ,
@@ -139,6 +139,180 @@ it('should not change error when TokenExpired happens', async () => {
139139 expect ( error ) . toBe ( expectedError )
140140} )
141141
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+
142316function newDirectConnectionProvider ( address , pool ) {
143317 const connectionProvider = new DirectConnectionProvider ( {
144318 id : 0 ,
@@ -150,22 +324,34 @@ function newDirectConnectionProvider (address, pool) {
150324 return connectionProvider
151325}
152326
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+ }
154334 return new Pool ( {
335+ config,
155336 create : ( address , release ) =>
156- Promise . resolve ( new FakeConnection ( address , release ) )
337+ Promise . resolve ( _create ( address , release ) ) ,
157338 } )
158339}
159340
160341class FakeConnection extends Connection {
161- constructor ( address , release ) {
342+ constructor ( address , release , server ) {
162343 super ( null )
163344
164345 this . _address = address
165- this . release = release
346+ this . _release = jest . fn ( ( ) => release ( address , this ) )
347+ this . _server = server
166348 }
167349
168- get address ( ) {
350+ get address ( ) {
169351 return this . _address
170352 }
353+
354+ get server ( ) {
355+ return this . _server
356+ }
171357}
0 commit comments