Skip to content

Introduce Testkit Reactive Backend #879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 22, 2022
7 changes: 6 additions & 1 deletion packages/testkit-backend/src/context.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
export default class Context {
constructor (shouldRunTest) {
constructor (shouldRunTest, getFeatures) {
this._id = 0
this._drivers = {}
this._sessions = {}
this._txs = {}
this._resolverRequests = {}
this._errors = {}
this._shouldRunTest = shouldRunTest
this._getFeatures = getFeatures
this._results = {}
}

Expand Down Expand Up @@ -101,6 +102,10 @@ export default class Context {
return this._shouldRunTest
}

getFeatures() {
return this._getFeatures()
}

_add (map, object) {
this._id++
map[this._id] = object
Expand Down
34 changes: 21 additions & 13 deletions packages/testkit-backend/src/controller/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ import stringify from '../stringify'
*/
export default class LocalController extends Controller {

constructor(requestHandlers = {}, shouldRunTest = () => {}) {
constructor(requestHandlers = {}, shouldRunTest = () => {}, getFeatures = () => []) {
super()
this._requestHandlers = requestHandlers
this._shouldRunTest = shouldRunTest
this._getFeatures = getFeatures
this._contexts = new Map()
}

openContext (contextId) {
this._contexts.set(contextId, new Context(this._shouldRunTest))
this._contexts.set(contextId, new Context(this._shouldRunTest, this._getFeatures))
}

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

return await this._requestHandlers[name](this._contexts.get(contextId), data, {
writeResponse: (name, data) => this._writeResponse(contextId, name, data),
writeResponse: (response) => this._writeResponse(contextId, response),
writeError: (e) => this._writeError(contextId, e),
writeBackendError: (msg) => this._writeBackendError(contextId, msg)
})

}

_writeResponse (contextId, name, data) {
console.log('> writing response', name, data)
let response = {
name: name,
data: data
}

_writeResponse (contextId, response) {
console.log('> writing response', response.name, response.data)
this.emit('response', { contextId, response })
}

_writeBackendError (contextId, msg) {
this._writeResponse(contextId, 'BackendError', { msg: msg })
this._writeResponse(contextId, newResponse('BackendError', { msg: msg }))
}

_writeError (contextId, e) {
if (e.name) {
const id = this._contexts.get(contextId).addError(e)
this._writeResponse(contextId, 'DriverError', {
this._writeResponse(contextId, newResponse('DriverError', {
id,
msg: e.message + ' (' + e.code + ')',
code: e.code
})
}))
return
}
this._writeBackendError(contextId, e)
}

_msg (name, data) {
return {
name, data
}
}

}

function newResponse (name, data) {
return {
name, data
}
}
8 changes: 8 additions & 0 deletions packages/testkit-backend/src/feature/async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const features = [
'Feature:API:Result.List',
'Feature:API:Result.Peek',
'Optimization:EagerTransactionBegin',
'Optimization:PullPipelining',
]

export default features
48 changes: 48 additions & 0 deletions packages/testkit-backend/src/feature/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import tls from 'tls'

const SUPPORTED_TLS = (() => {
if (tls.DEFAULT_MAX_VERSION) {
const min = Number(tls.DEFAULT_MIN_VERSION.split('TLSv')[1])
const max = Number(tls.DEFAULT_MAX_VERSION.split('TLSv')[1])
const result = [];
for (let version = min > 1 ? min : 1.1; version <= max; version = Number((version + 0.1).toFixed(1)) ) {
result.push(`Feature:TLS:${version.toFixed(1)}`)
}
return result;
}
return [];
})();

const features = [
'Feature:Auth:Custom',
'Feature:Auth:Kerberos',
'Feature:Auth:Bearer',
'Feature:API:SSLConfig',
'Feature:API:SSLSchemes',
'AuthorizationExpiredTreatment',
'ConfHint:connection.recv_timeout_seconds',
'Feature:Impersonation',
'Feature:Bolt:3.0',
'Feature:Bolt:4.1',
'Feature:Bolt:4.2',
'Feature:Bolt:4.3',
'Feature:Bolt:4.4',
'Feature:API:Driver:GetServerInfo',
'Feature:API:Driver.VerifyConnectivity',
'Feature:API:Result.Peek',
'Feature:Configuration:ConnectionAcquisitionTimeout',
'Optimization:ImplicitDefaultArguments',
'Temporary:ConnectionAcquisitionTimeout',
'Temporary:CypherPathAndRelationship',
'Temporary:DriverFetchSize',
'Temporary:DriverMaxConnectionPoolSize',
'Temporary:DriverMaxTxRetryTime',
'Temporary:GetConnectionPoolMetrics',
'Temporary:FastFailingDiscovery',
'Temporary:FullSummary',
'Temporary:ResultKeys',
'Temporary:TransactionClose',
...SUPPORTED_TLS
]

export default features
18 changes: 18 additions & 0 deletions packages/testkit-backend/src/feature/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import commonFeatures from './common'
import rxFeatures from './rx'
import asyncFeatures from './async'

const featuresByContext = new Map([
['async', asyncFeatures],
['rx', rxFeatures],
])


export function createGetFeatures (contexts) {
const features = contexts
.filter(context => featuresByContext.has(context))
.map(context => featuresByContext.get(context))
.reduce((previous, current) => [ ...previous, ...current ], commonFeatures)

return () => features
}
6 changes: 6 additions & 0 deletions packages/testkit-backend/src/feature/rx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

const features = [

]

export default features
19 changes: 15 additions & 4 deletions packages/testkit-backend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import Backend from './backend'
import { SocketChannel, WebSocketChannel } from './channel'
import { LocalController, RemoteController } from './controller'
import { getShouldRunTest } from './skipped-tests'
import * as REQUEST_HANDLERS from './request-handlers'
import { createGetFeatures } from './feature'
import * as REQUEST_HANDLERS from './request-handlers.js'
import * as RX_REQUEST_HANDLERS from './request-handlers-rx.js'

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

const shouldRunTest = getShouldRunTest(driverDescriptorList)
const shouldRunTest = getShouldRunTest([...driverDescriptorList, sessionTypeDescriptor])
const getFeatures = createGetFeatures([sessionTypeDescriptor])

const newChannel = () => {
if ( channelType.toUpperCase() === 'WEBSOCKET' ) {
return new WebSocketChannel(new URL(`ws://localhost:${backendPort}`))

}
return new SocketChannel(backendPort)
}
Expand All @@ -30,7 +34,7 @@ function main( ) {
if ( testEnviroment.toUpperCase() === 'REMOTE' ) {
return new RemoteController(webserverPort)
}
return new LocalController(REQUEST_HANDLERS, shouldRunTest)
return new LocalController(getRequestHandlers(sessionType), shouldRunTest, getFeatures)
}

const backend = new Backend(newController, newChannel)
Expand All @@ -52,4 +56,11 @@ function main( ) {
}
}

function getRequestHandlers(sessionType) {
if (sessionType.toUpperCase() === 'RX') {
return RX_REQUEST_HANDLERS
}
return REQUEST_HANDLERS
}

main()
Loading