Skip to content

Commit 5ef3add

Browse files
authored
Introduce Testkit Reactive Backend (#879)
This implementation of the Testkit Backend handles requests with using the `driver.rxSession`, so this is not compatible with the `neo4j-driver-lite`. For introducing the new backend handlers, the previous ones had to be refactor for decoupling part of the code for the protocol and enable it to be used by the two set of handlers.
1 parent a816c08 commit 5ef3add

File tree

12 files changed

+585
-125
lines changed

12 files changed

+585
-125
lines changed

packages/testkit-backend/src/context.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
export default class Context {
2-
constructor (shouldRunTest) {
2+
constructor (shouldRunTest, getFeatures) {
33
this._id = 0
44
this._drivers = {}
55
this._sessions = {}
66
this._txs = {}
77
this._resolverRequests = {}
88
this._errors = {}
99
this._shouldRunTest = shouldRunTest
10+
this._getFeatures = getFeatures
1011
this._results = {}
1112
}
1213

@@ -101,6 +102,10 @@ export default class Context {
101102
return this._shouldRunTest
102103
}
103104

105+
getFeatures() {
106+
return this._getFeatures()
107+
}
108+
104109
_add (map, object) {
105110
this._id++
106111
map[this._id] = object

packages/testkit-backend/src/controller/local.js

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ import stringify from '../stringify'
1010
*/
1111
export default class LocalController extends Controller {
1212

13-
constructor(requestHandlers = {}, shouldRunTest = () => {}) {
13+
constructor(requestHandlers = {}, shouldRunTest = () => {}, getFeatures = () => []) {
1414
super()
1515
this._requestHandlers = requestHandlers
1616
this._shouldRunTest = shouldRunTest
17+
this._getFeatures = getFeatures
1718
this._contexts = new Map()
1819
}
1920

2021
openContext (contextId) {
21-
this._contexts.set(contextId, new Context(this._shouldRunTest))
22+
this._contexts.set(contextId, new Context(this._shouldRunTest, this._getFeatures))
2223
}
2324

2425
closeContext (contextId) {
@@ -35,38 +36,45 @@ export default class LocalController extends Controller {
3536
}
3637

3738
return await this._requestHandlers[name](this._contexts.get(contextId), data, {
38-
writeResponse: (name, data) => this._writeResponse(contextId, name, data),
39+
writeResponse: (response) => this._writeResponse(contextId, response),
3940
writeError: (e) => this._writeError(contextId, e),
4041
writeBackendError: (msg) => this._writeBackendError(contextId, msg)
4142
})
4243

4344
}
4445

45-
_writeResponse (contextId, name, data) {
46-
console.log('> writing response', name, data)
47-
let response = {
48-
name: name,
49-
data: data
50-
}
51-
46+
_writeResponse (contextId, response) {
47+
console.log('> writing response', response.name, response.data)
5248
this.emit('response', { contextId, response })
5349
}
5450

5551
_writeBackendError (contextId, msg) {
56-
this._writeResponse(contextId, 'BackendError', { msg: msg })
52+
this._writeResponse(contextId, newResponse('BackendError', { msg: msg }))
5753
}
5854

5955
_writeError (contextId, e) {
6056
if (e.name) {
6157
const id = this._contexts.get(contextId).addError(e)
62-
this._writeResponse(contextId, 'DriverError', {
58+
this._writeResponse(contextId, newResponse('DriverError', {
6359
id,
6460
msg: e.message + ' (' + e.code + ')',
6561
code: e.code
66-
})
62+
}))
6763
return
6864
}
6965
this._writeBackendError(contextId, e)
7066
}
67+
68+
_msg (name, data) {
69+
return {
70+
name, data
71+
}
72+
}
7173

7274
}
75+
76+
function newResponse (name, data) {
77+
return {
78+
name, data
79+
}
80+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const features = [
2+
'Feature:API:Result.List',
3+
'Feature:API:Result.Peek',
4+
'Optimization:EagerTransactionBegin',
5+
'Optimization:PullPipelining',
6+
]
7+
8+
export default features
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import tls from 'tls'
2+
3+
const SUPPORTED_TLS = (() => {
4+
if (tls.DEFAULT_MAX_VERSION) {
5+
const min = Number(tls.DEFAULT_MIN_VERSION.split('TLSv')[1])
6+
const max = Number(tls.DEFAULT_MAX_VERSION.split('TLSv')[1])
7+
const result = [];
8+
for (let version = min > 1 ? min : 1.1; version <= max; version = Number((version + 0.1).toFixed(1)) ) {
9+
result.push(`Feature:TLS:${version.toFixed(1)}`)
10+
}
11+
return result;
12+
}
13+
return [];
14+
})();
15+
16+
const features = [
17+
'Feature:Auth:Custom',
18+
'Feature:Auth:Kerberos',
19+
'Feature:Auth:Bearer',
20+
'Feature:API:SSLConfig',
21+
'Feature:API:SSLSchemes',
22+
'AuthorizationExpiredTreatment',
23+
'ConfHint:connection.recv_timeout_seconds',
24+
'Feature:Impersonation',
25+
'Feature:Bolt:3.0',
26+
'Feature:Bolt:4.1',
27+
'Feature:Bolt:4.2',
28+
'Feature:Bolt:4.3',
29+
'Feature:Bolt:4.4',
30+
'Feature:API:Driver:GetServerInfo',
31+
'Feature:API:Driver.VerifyConnectivity',
32+
'Feature:API:Result.Peek',
33+
'Feature:Configuration:ConnectionAcquisitionTimeout',
34+
'Optimization:ImplicitDefaultArguments',
35+
'Temporary:ConnectionAcquisitionTimeout',
36+
'Temporary:CypherPathAndRelationship',
37+
'Temporary:DriverFetchSize',
38+
'Temporary:DriverMaxConnectionPoolSize',
39+
'Temporary:DriverMaxTxRetryTime',
40+
'Temporary:GetConnectionPoolMetrics',
41+
'Temporary:FastFailingDiscovery',
42+
'Temporary:FullSummary',
43+
'Temporary:ResultKeys',
44+
'Temporary:TransactionClose',
45+
...SUPPORTED_TLS
46+
]
47+
48+
export default features
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import commonFeatures from './common'
2+
import rxFeatures from './rx'
3+
import asyncFeatures from './async'
4+
5+
const featuresByContext = new Map([
6+
['async', asyncFeatures],
7+
['rx', rxFeatures],
8+
])
9+
10+
11+
export function createGetFeatures (contexts) {
12+
const features = contexts
13+
.filter(context => featuresByContext.has(context))
14+
.map(context => featuresByContext.get(context))
15+
.reduce((previous, current) => [ ...previous, ...current ], commonFeatures)
16+
17+
return () => features
18+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
const features = [
3+
4+
]
5+
6+
export default features

packages/testkit-backend/src/index.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import Backend from './backend'
22
import { SocketChannel, WebSocketChannel } from './channel'
33
import { LocalController, RemoteController } from './controller'
44
import { getShouldRunTest } from './skipped-tests'
5-
import * as REQUEST_HANDLERS from './request-handlers'
5+
import { createGetFeatures } from './feature'
6+
import * as REQUEST_HANDLERS from './request-handlers.js'
7+
import * as RX_REQUEST_HANDLERS from './request-handlers-rx.js'
68

79
/**
810
* Responsible for configure and run the backend server.
@@ -13,15 +15,17 @@ function main( ) {
1315
const backendPort = process.env.BACKEND_PORT || 9876
1416
const webserverPort = process.env.WEB_SERVER_PORT || 8000
1517
const driverDescriptor = process.env.DRIVER_DESCRIPTOR || ''
18+
const sessionType = process.env.SESSION_TYPE || 'ASYNC'
19+
const sessionTypeDescriptor = sessionType === 'RX' ? 'rx' : 'async'
1620
const driverDescriptorList = driverDescriptor
1721
.split(',').map(s => s.trim().toLowerCase())
1822

19-
const shouldRunTest = getShouldRunTest(driverDescriptorList)
23+
const shouldRunTest = getShouldRunTest([...driverDescriptorList, sessionTypeDescriptor])
24+
const getFeatures = createGetFeatures([sessionTypeDescriptor])
2025

2126
const newChannel = () => {
2227
if ( channelType.toUpperCase() === 'WEBSOCKET' ) {
2328
return new WebSocketChannel(new URL(`ws://localhost:${backendPort}`))
24-
2529
}
2630
return new SocketChannel(backendPort)
2731
}
@@ -30,7 +34,7 @@ function main( ) {
3034
if ( testEnviroment.toUpperCase() === 'REMOTE' ) {
3135
return new RemoteController(webserverPort)
3236
}
33-
return new LocalController(REQUEST_HANDLERS, shouldRunTest)
37+
return new LocalController(getRequestHandlers(sessionType), shouldRunTest, getFeatures)
3438
}
3539

3640
const backend = new Backend(newController, newChannel)
@@ -52,4 +56,11 @@ function main( ) {
5256
}
5357
}
5458

59+
function getRequestHandlers(sessionType) {
60+
if (sessionType.toUpperCase() === 'RX') {
61+
return RX_REQUEST_HANDLERS
62+
}
63+
return REQUEST_HANDLERS
64+
}
65+
5566
main()

0 commit comments

Comments
 (0)