From 993c9f5ba47bd1b5a884b718fb96cb3817ee13f5 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Tue, 26 Oct 2021 18:02:30 +0200 Subject: [PATCH 01/12] testkit-backend: Separate the socket connection, protocol and controller The logic of reading and writing in the socket, call the handlers and parse the messages were mixed in the Backend class. This makes difficult to add different protocols, socket implementation or controllers to the backend. The goal of this change is separate this three concerns in `SocketServer`, `Controller` and `Protocol` with the `Backend` class as the glue between these concepts. New implementations of the `Controller` could enable this backend to test the driver running in the browser without have to change the logic of parsing the messages between testkit and testkit-backend, for instance. --- packages/testkit-backend/package.json | 2 +- packages/testkit-backend/src/backend.js | 36 ++++++ packages/testkit-backend/src/controller.js | 24 ++++ packages/testkit-backend/src/index.js | 19 +++ packages/testkit-backend/src/main.js | 117 ------------------ .../testkit-backend/src/node.controller.js | 67 ++++++++++ packages/testkit-backend/src/protocol.js | 65 ++++++++++ packages/testkit-backend/src/socket.server.js | 75 +++++++++++ 8 files changed, 287 insertions(+), 118 deletions(-) create mode 100644 packages/testkit-backend/src/backend.js create mode 100644 packages/testkit-backend/src/controller.js create mode 100644 packages/testkit-backend/src/index.js delete mode 100644 packages/testkit-backend/src/main.js create mode 100644 packages/testkit-backend/src/node.controller.js create mode 100644 packages/testkit-backend/src/protocol.js create mode 100644 packages/testkit-backend/src/socket.server.js diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 8d050630c..c532d7bed 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -6,7 +6,7 @@ "private": true, "type": "module", "scripts": { - "start": "node -r esm src/main.js", + "start": "node -r esm src/index.js", "clean": "rm -fr node_modules" }, "repository": { diff --git a/packages/testkit-backend/src/backend.js b/packages/testkit-backend/src/backend.js new file mode 100644 index 000000000..2fe11cb3f --- /dev/null +++ b/packages/testkit-backend/src/backend.js @@ -0,0 +1,36 @@ +import SocketServer from './socket.server' +import Controller from './controller' + +export default class Backend { + constructor (port, newController = () => new Controller(), newSocketServer = port => new SocketServer(port)) { + this._socketServer = newSocketServer(port) + this._controller = newController() + + this._controller.on('response', ({ contextId, response }) => { + this._socketServer.writeResponse(contextId, response.name, response.data) + }) + + this._socketServer.on('contextOpen', ({ contextId }) => this._controller.onContextOpen(contextId)) + this._socketServer.on('contextClose', ({ contextId }) => this._controller.onContextClose(contextId)) + + this._socketServer.on('request', ({ contextId, request }) => { + try { + this._controller.handle(contextId, request.name, request.data ) + } catch (e) { + this._socketServer.writeBackendError(contextId, e) + } + }) + } + + start () { + this._controller.start() + this._socketServer.start() + } + + stop () { + this._socketServer.stop() + this._controller.stop() + } + +} + diff --git a/packages/testkit-backend/src/controller.js b/packages/testkit-backend/src/controller.js new file mode 100644 index 000000000..f73a74610 --- /dev/null +++ b/packages/testkit-backend/src/controller.js @@ -0,0 +1,24 @@ +import { EventEmitter } from 'events' + +export default class Controller extends EventEmitter { + + start () { + + } + + stop () { + + } + + onContextOpen(contextId) { + throw new Error('not implemented') + } + + onContextClose(contextId) { + throw new Error('not implemented') + } + + handle(contextId, name, data) { + throw new Error('not implemented') + } +} \ No newline at end of file diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js new file mode 100644 index 000000000..31a69d5fe --- /dev/null +++ b/packages/testkit-backend/src/index.js @@ -0,0 +1,19 @@ +import Backend from './backend' +import NodeController from './node.controller' + +function main( ) { + const backend = new Backend(process.env.BACKEND_PORT || 9876, () => new NodeController()) + + backend.start() + + // cleaning up + process.on('exit', backend.stop.bind(backend)); + + // Capturing signals + process.on('SIGINT', process.exit.bind(process)); + process.on('SIGUSR1', process.exit.bind(process)); + process.on('SIGUSR2', process.exit.bind(process)); + process.on('uncaughtException', process.exit.bind(process)); +} + +main() \ No newline at end of file diff --git a/packages/testkit-backend/src/main.js b/packages/testkit-backend/src/main.js deleted file mode 100644 index abf0315bf..000000000 --- a/packages/testkit-backend/src/main.js +++ /dev/null @@ -1,117 +0,0 @@ -import net from 'net' -import readline from 'readline' -import Context from './context.js' -import * as requestHandlers from './request-handlers.js' - -class Backend { - constructor ({ writer }) { - console.log('Backend connected') - this._inRequest = false - this._request = '' - // Event handlers need to be bound to this instance - this.onLine = this.onLine.bind(this) - this._writer = writer - this._context = new Context() - } - - // Called whenever a new line is received. - onLine (line) { - switch (line) { - case '#request begin': - if (this._inRequest) { - throw new Error('Already in request') - } - this._inRequest = true - break - case '#request end': - if (!this._inRequest) { - throw new Error('End while not in request') - } - try { - this._handleRequest(this._request) - } catch (e) { - this._writeBackendError(e) - } - this._request = '' - this._inRequest = false - break - default: - if (!this._inRequest) { - throw new Error('Line while not in request') - } - this._request += line - break - } - } - - _handleRequest (request) { - request = JSON.parse(request) - const { name, data } = request - console.log('> Got request ' + name, data) - - if (name in requestHandlers) { - requestHandlers[name](this._context, data, { - writeResponse: this._writeResponse.bind(this), - writeError: this._writeError.bind(this), - writeBackendError: this._writeBackendError.bind(this) - }) - return - } - - this._writeBackendError('Unknown request: ' + name) - console.log('Unknown request: ' + name) - console.log(stringify(data)) - } - - _writeResponse (name, data) { - console.log('> writing response', name, data) - let response = { - name: name, - data: data - } - response = stringify(response) - const lines = ['#response begin', response, '#response end'] - this._writer(lines) - } - - _writeBackendError (msg) { - this._writeResponse('BackendError', { msg: msg }) - } - - _writeError (e) { - if (e.name) { - const id = this._context.addError(e) - this._writeResponse('DriverError', { - id, - msg: e.message + ' (' + e.code + ')', - code: e.code - }) - return - } - this._writeBackendError(e) - } -} - -function stringify (val) { - return JSON.stringify(val, (_, value) => - typeof value === 'bigint' ? `${value}n` : value - ) -} - -function server () { - const server = net.createServer(conn => { - const backend = new Backend({ - writer: lines => { - const chunk = lines.join('\n') + '\n' - conn.write(chunk, 'utf8', () => {}) - } - }) - conn.setEncoding('utf8') - const iface = readline.createInterface(conn, null) - iface.on('line', backend.onLine) - }) - server.listen(9876, () => { - console.log('Listening') - }) -} -server() diff --git a/packages/testkit-backend/src/node.controller.js b/packages/testkit-backend/src/node.controller.js new file mode 100644 index 000000000..c5ee7c691 --- /dev/null +++ b/packages/testkit-backend/src/node.controller.js @@ -0,0 +1,67 @@ +import Context from './context' +import Controller from './controller' +import * as _requestHandlers from './request-handlers' + + +export default class NodeController extends Controller { + + constructor(requestHandlers = _requestHandlers) { + super() + this._requestHandlers = requestHandlers + this._contexts = new Map() + } + + onContextOpen(contextId) { + this._contexts.set(contextId, new Context()) + } + + onContextClose(contextId) { + this._contexts.delete(contextId) + } + + + handle(contextId, name, data) { + if (!this._contexts.has(contextId)) { + throw new Error(`Context ${contextId} does not exist`) + } else if (!(name in this._requestHandlers)) { + console.log('Unknown request: ' + name) + console.log(stringify(data)) + throw new Error(`Unknown request: ${name}`) + } + + this._requestHandlers[name](this._contexts.get(contextId), data, { + writeResponse: (name, data) => this._writeResponse(contextId, name, data), + 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 + } + + this.emit('response', { contextId, response }) + } + + _writeBackendError (contextId, msg) { + this._writeResponse(contextId, 'BackendError', { msg: msg }) + } + + _writeError (contextId, e) { + if (e.name) { + const id = this._contexts.get(contextId).addError(e) + this._writeResponse(contextId, 'DriverError', { + id, + msg: e.message + ' (' + e.code + ')', + code: e.code + }) + return + } + this._writeBackendError(contextId, e) + } + +} \ No newline at end of file diff --git a/packages/testkit-backend/src/protocol.js b/packages/testkit-backend/src/protocol.js new file mode 100644 index 000000000..49124f3fd --- /dev/null +++ b/packages/testkit-backend/src/protocol.js @@ -0,0 +1,65 @@ + +import EventEmitter from 'events' + +export default class Protocol extends EventEmitter { + constructor () { + super() + console.log('Backend connected') + this._inRequest = false + this._request = '' + } + + // Called whenever a new line is received. + processLine (line) { + switch (line) { + case '#request begin': + if (this._inRequest) { + throw new Error('Already in request') + } + this._inRequest = true + break + case '#request end': + if (!this._inRequest) { + throw new Error('End while not in request') + } + try { + this._emitRequest() + } catch (e) { + console.log('error', e) + this.emit('error', e) + } + this._request = '' + this._inRequest = false + break + default: + if (!this._inRequest) { + throw new Error('Line while not in request') + } + this._request += line + break + } + } + + serializeResponse (name, data) { + console.log('> writing response', name, data) + let response = { + name: name, + data: data + } + response = this._stringify(response) + return ['#response begin', response, '#response end'].join('\n') + '\n' + } + + _emitRequest () { + const request = JSON.parse(this._request) + const { name, data } = request + console.log('> Got request ' + name, data) + this.emit('request', { name, data }) + } + + _stringify (val) { + return JSON.stringify(val, (_, value) => + typeof value === 'bigint' ? `${value}n` : value + ) + } +} \ No newline at end of file diff --git a/packages/testkit-backend/src/socket.server.js b/packages/testkit-backend/src/socket.server.js new file mode 100644 index 000000000..78dfeaf79 --- /dev/null +++ b/packages/testkit-backend/src/socket.server.js @@ -0,0 +1,75 @@ + +import readline from 'readline' +import { EventEmitter } from 'events' +import net from 'net' +import { randomBytes } from 'crypto' +import Protocol from './protocol' + +function generateRandomId () { + return randomBytes(16).toString() +} + +export default class SocketServer extends EventEmitter { + constructor(port, newProtocol = () => new Protocol(), newId = generateRandomId ) { + super() + this._newProtocol = newProtocol + this._server = null + this._newId = newId + this._clients = new Map() + this._port = port + } + + start () { + if (!this._server) { + this._server = net.createServer(connection => { + const contextId = this._newId() + console.log(`[${contextId}] Creating connection`) + const protocol = this._newProtocol() + + this._clients.set(contextId, { + protocol, + connection + }) + + this.emit('contextOpen', { contextId }) + protocol.on('request', request => this.emit('request', { contextId, request }) ) + protocol.on('error', e => this.writeBackendError(contextId, e)) + + connection.on('end', () => { + this._clients.delete(contextId) + this.emit('contextClose', { contextId }) + }) + + const iface = readline.createInterface(connection, null) + iface.on('line', protocol.processLine.bind(protocol)) + }) + + this._server.listen(this._port, () => { + console.log('Listening') + }) + + this._server.on('close', () => this.emit('close')) + } + } + + writeResponse (contextId, name, data) { + if (this._clients.has(contextId)) { + const { protocol, connection } = this._clients.get(contextId) + const chunk = protocol.serializeResponse(name, data) + connection.write(chunk, 'utf8', () => {}) + + } + } + + writeBackendError (contextId, error) { + this.writeResponse(contextId, 'BackendError', { msg: error}) + } + + stop () { + if (this._server) { + this._server.close() + this._clients = new Map() + } + } + +} From 6c51f5d747d0cbf12d1c1940dbd6896a13419d5e Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Wed, 27 Oct 2021 11:17:43 +0200 Subject: [PATCH 02/12] Improve design --- packages/testkit-backend/src/backend.js | 5 +- packages/testkit-backend/src/controller.js | 4 +- .../testkit-backend/src/node.controller.js | 4 +- packages/testkit-backend/src/protocol.js | 45 ++++++++----- packages/testkit-backend/src/socket.server.js | 63 ++++++++++--------- 5 files changed, 69 insertions(+), 52 deletions(-) diff --git a/packages/testkit-backend/src/backend.js b/packages/testkit-backend/src/backend.js index 2fe11cb3f..4741dc606 100644 --- a/packages/testkit-backend/src/backend.js +++ b/packages/testkit-backend/src/backend.js @@ -7,7 +7,7 @@ export default class Backend { this._controller = newController() this._controller.on('response', ({ contextId, response }) => { - this._socketServer.writeResponse(contextId, response.name, response.data) + this._socketServer.writeResponse(contextId, response) }) this._socketServer.on('contextOpen', ({ contextId }) => this._controller.onContextOpen(contextId)) @@ -15,7 +15,7 @@ export default class Backend { this._socketServer.on('request', ({ contextId, request }) => { try { - this._controller.handle(contextId, request.name, request.data ) + this._controller.handle(contextId, request) } catch (e) { this._socketServer.writeBackendError(contextId, e) } @@ -33,4 +33,3 @@ export default class Backend { } } - diff --git a/packages/testkit-backend/src/controller.js b/packages/testkit-backend/src/controller.js index f73a74610..e6876e8c9 100644 --- a/packages/testkit-backend/src/controller.js +++ b/packages/testkit-backend/src/controller.js @@ -18,7 +18,7 @@ export default class Controller extends EventEmitter { throw new Error('not implemented') } - handle(contextId, name, data) { + handle(contextId, request) { throw new Error('not implemented') } -} \ No newline at end of file +} diff --git a/packages/testkit-backend/src/node.controller.js b/packages/testkit-backend/src/node.controller.js index c5ee7c691..e92a62834 100644 --- a/packages/testkit-backend/src/node.controller.js +++ b/packages/testkit-backend/src/node.controller.js @@ -20,7 +20,7 @@ export default class NodeController extends Controller { } - handle(contextId, name, data) { + handle(contextId, { name, data }) { if (!this._contexts.has(contextId)) { throw new Error(`Context ${contextId} does not exist`) } else if (!(name in this._requestHandlers)) { @@ -64,4 +64,4 @@ export default class NodeController extends Controller { this._writeBackendError(contextId, e) } -} \ No newline at end of file +} diff --git a/packages/testkit-backend/src/protocol.js b/packages/testkit-backend/src/protocol.js index 49124f3fd..bacc41e64 100644 --- a/packages/testkit-backend/src/protocol.js +++ b/packages/testkit-backend/src/protocol.js @@ -1,16 +1,31 @@ - +import readline from 'readline' import EventEmitter from 'events' export default class Protocol extends EventEmitter { - constructor () { + constructor (stream) { super() - console.log('Backend connected') this._inRequest = false this._request = '' + this._stream = stream + this._readlineInterface = null + } + + start() { + if (!this._readlineInterface) { + this._readlineInterface = readline.createInterface(this._stream, null) + this._readlineInterface.on('line', this._processLine.bind(this)) + } + } + + stop () { + if (this._readlineInterface) { + this._readlineInterface.off('line', this._processLine.bind(this)) + this._readlineInterface = null + } } // Called whenever a new line is received. - processLine (line) { + _processLine (line) { switch (line) { case '#request begin': if (this._inRequest) { @@ -26,28 +41,28 @@ export default class Protocol extends EventEmitter { this._emitRequest() } catch (e) { console.log('error', e) - this.emit('error', e) + this._emitError(e) } this._request = '' this._inRequest = false break default: if (!this._inRequest) { - throw new Error('Line while not in request') + this._emitError(new Error('Line while not in request')) } this._request += line break } } - serializeResponse (name, data) { - console.log('> writing response', name, data) - let response = { - name: name, - data: data - } - response = this._stringify(response) - return ['#response begin', response, '#response end'].join('\n') + '\n' + _emitError(e) { + this.emit('error', e) + } + + serializeResponse (response) { + console.log('> writing response', response) + const responseStr = this._stringify(response) + return ['#response begin', responseStr, '#response end'].join('\n') + '\n' } _emitRequest () { @@ -62,4 +77,4 @@ export default class Protocol extends EventEmitter { typeof value === 'bigint' ? `${value}n` : value ) } -} \ No newline at end of file +} diff --git a/packages/testkit-backend/src/socket.server.js b/packages/testkit-backend/src/socket.server.js index 78dfeaf79..d5ad808bb 100644 --- a/packages/testkit-backend/src/socket.server.js +++ b/packages/testkit-backend/src/socket.server.js @@ -1,5 +1,3 @@ - -import readline from 'readline' import { EventEmitter } from 'events' import net from 'net' import { randomBytes } from 'crypto' @@ -10,7 +8,7 @@ function generateRandomId () { } export default class SocketServer extends EventEmitter { - constructor(port, newProtocol = () => new Protocol(), newId = generateRandomId ) { + constructor(port, newProtocol = stream => new Protocol(stream), newId = generateRandomId ) { super() this._newProtocol = newProtocol this._server = null @@ -21,28 +19,7 @@ export default class SocketServer extends EventEmitter { start () { if (!this._server) { - this._server = net.createServer(connection => { - const contextId = this._newId() - console.log(`[${contextId}] Creating connection`) - const protocol = this._newProtocol() - - this._clients.set(contextId, { - protocol, - connection - }) - - this.emit('contextOpen', { contextId }) - protocol.on('request', request => this.emit('request', { contextId, request }) ) - protocol.on('error', e => this.writeBackendError(contextId, e)) - - connection.on('end', () => { - this._clients.delete(contextId) - this.emit('contextClose', { contextId }) - }) - - const iface = readline.createInterface(connection, null) - iface.on('line', protocol.processLine.bind(protocol)) - }) + this._server = net.createServer(this._handleConnection.bind(this)) this._server.listen(this._port, () => { console.log('Listening') @@ -52,24 +29,50 @@ export default class SocketServer extends EventEmitter { } } - writeResponse (contextId, name, data) { + _handleConnection(connection) { + console.log('Backend connected') + + const contextId = this._newId() + const protocol = this._newProtocol(connection) + + this._clients.set(contextId, { + protocol, + connection + }) + + this.emit('contextOpen', { contextId }) + protocol.on('request', request => this.emit('request', { contextId, request }) ) + protocol.on('error', e => this.writeBackendError(contextId, e)) + + connection.on('end', () => { + if (this._clients.has(contextId)) { + this._clients.get(contextId).protocol.stop() + } + this._clients.delete(contextId) + this.emit('contextClose', { contextId }) + }) + + protocol.start() + } + + writeResponse (contextId, response) { if (this._clients.has(contextId)) { const { protocol, connection } = this._clients.get(contextId) - const chunk = protocol.serializeResponse(name, data) + const chunk = protocol.serializeResponse(response) connection.write(chunk, 'utf8', () => {}) - } } writeBackendError (contextId, error) { - this.writeResponse(contextId, 'BackendError', { msg: error}) + this.writeResponse(contextId, { name: 'BackendError', data: { msg: error } }) } stop () { if (this._server) { this._server.close() + this._server = null + this._clients.forEach(client => client.protocol.stop()) this._clients = new Map() } } - } From a27edba8edb33e20284ac7a28fdda974dee9d281 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 11 Nov 2021 13:38:48 +0100 Subject: [PATCH 03/12] Extracting channel module --- packages/testkit-backend/src/backend.js | 28 ++++++++++++------- .../testkit-backend/src/channel/abstract.js | 21 ++++++++++++++ packages/testkit-backend/src/channel/index.js | 7 +++++ .../{socket.server.js => channel/socket.js} | 4 +-- .../testkit-protocol.js} | 0 packages/testkit-backend/src/index.js | 7 +++-- 6 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 packages/testkit-backend/src/channel/abstract.js create mode 100644 packages/testkit-backend/src/channel/index.js rename packages/testkit-backend/src/{socket.server.js => channel/socket.js} (94%) rename packages/testkit-backend/src/{protocol.js => channel/testkit-protocol.js} (100%) diff --git a/packages/testkit-backend/src/backend.js b/packages/testkit-backend/src/backend.js index 4741dc606..5c59bd1ed 100644 --- a/packages/testkit-backend/src/backend.js +++ b/packages/testkit-backend/src/backend.js @@ -1,34 +1,42 @@ -import SocketServer from './socket.server' +import Channel from './channel' import Controller from './controller' +/** + * Binds Channel and Controller + */ export default class Backend { - constructor (port, newController = () => new Controller(), newSocketServer = port => new SocketServer(port)) { - this._socketServer = newSocketServer(port) + /** + * + * @param {function():Controller} newController The controller factory function + * @param {function():Channel} newChannel The channel factory function + */ + constructor (newController, newChannel) { + this._channel = newChannel() this._controller = newController() this._controller.on('response', ({ contextId, response }) => { - this._socketServer.writeResponse(contextId, response) + this._channel.writeResponse(contextId, response) }) - this._socketServer.on('contextOpen', ({ contextId }) => this._controller.onContextOpen(contextId)) - this._socketServer.on('contextClose', ({ contextId }) => this._controller.onContextClose(contextId)) + this._channel.on('contextOpen', ({ contextId }) => this._controller.onContextOpen(contextId)) + this._channel.on('contextClose', ({ contextId }) => this._controller.onContextClose(contextId)) - this._socketServer.on('request', ({ contextId, request }) => { + this._channel.on('request', ({ contextId, request }) => { try { this._controller.handle(contextId, request) } catch (e) { - this._socketServer.writeBackendError(contextId, e) + this._channel.writeBackendError(contextId, e) } }) } start () { this._controller.start() - this._socketServer.start() + this._channel.start() } stop () { - this._socketServer.stop() + this._channel.stop() this._controller.stop() } diff --git a/packages/testkit-backend/src/channel/abstract.js b/packages/testkit-backend/src/channel/abstract.js new file mode 100644 index 000000000..79e4be20c --- /dev/null +++ b/packages/testkit-backend/src/channel/abstract.js @@ -0,0 +1,21 @@ +import { EventEmitter } from "events" + +export default class Channel extends EventEmitter { + + start () { + throw Error('Not implemented') + } + + stop () { + throw Error('Not implemented') + } + + writeResponse (contextId, response) { + throw Error('Not implemented') + } + + writeBackendError (contextId, error) { + this.writeResponse(contextId, { name: 'BackendError', data: { msg: error } }) + } + +} \ No newline at end of file diff --git a/packages/testkit-backend/src/channel/index.js b/packages/testkit-backend/src/channel/index.js new file mode 100644 index 000000000..64d0ba18a --- /dev/null +++ b/packages/testkit-backend/src/channel/index.js @@ -0,0 +1,7 @@ +import Channel from "./abstract" +import SocketChannel from "./socket" + +export default Channel +export { + SocketChannel +} \ No newline at end of file diff --git a/packages/testkit-backend/src/socket.server.js b/packages/testkit-backend/src/channel/socket.js similarity index 94% rename from packages/testkit-backend/src/socket.server.js rename to packages/testkit-backend/src/channel/socket.js index d5ad808bb..cb173c67b 100644 --- a/packages/testkit-backend/src/socket.server.js +++ b/packages/testkit-backend/src/channel/socket.js @@ -1,7 +1,7 @@ import { EventEmitter } from 'events' import net from 'net' import { randomBytes } from 'crypto' -import Protocol from './protocol' +import Protocol from './testkit-protocol' function generateRandomId () { return randomBytes(16).toString() @@ -42,7 +42,7 @@ export default class SocketServer extends EventEmitter { this.emit('contextOpen', { contextId }) protocol.on('request', request => this.emit('request', { contextId, request }) ) - protocol.on('error', e => this.writeBackendError(contextId, e)) + protocol.on('error', e => this._writeBackendError(contextId, e)) connection.on('end', () => { if (this._clients.has(contextId)) { diff --git a/packages/testkit-backend/src/protocol.js b/packages/testkit-backend/src/channel/testkit-protocol.js similarity index 100% rename from packages/testkit-backend/src/protocol.js rename to packages/testkit-backend/src/channel/testkit-protocol.js diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js index 31a69d5fe..a0ead9a17 100644 --- a/packages/testkit-backend/src/index.js +++ b/packages/testkit-backend/src/index.js @@ -1,8 +1,11 @@ import Backend from './backend' +import { SocketChannel } from './channel' import NodeController from './node.controller' function main( ) { - const backend = new Backend(process.env.BACKEND_PORT || 9876, () => new NodeController()) + const newChannel = () => new SocketChannel(process.env.BACKEND_PORT || 9876) + const newController = () => new NodeController() + const backend = new Backend(newController, newChannel) backend.start() @@ -16,4 +19,4 @@ function main( ) { process.on('uncaughtException', process.exit.bind(process)); } -main() \ No newline at end of file +main() From c6f4826000df9533df9c27dc65d72143e2fc7c76 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 11 Nov 2021 13:58:54 +0100 Subject: [PATCH 04/12] Extract controller --- packages/testkit-backend/src/channel/index.js | 4 ++-- .../src/channel/{abstract.js => interface.js} | 2 +- packages/testkit-backend/src/controller/index.js | 7 +++++++ .../src/{controller.js => controller/interface.js} | 0 .../src/{node.controller.js => controller/local.js} | 9 ++++----- packages/testkit-backend/src/index.js | 5 +++-- 6 files changed, 17 insertions(+), 10 deletions(-) rename packages/testkit-backend/src/channel/{abstract.js => interface.js} (99%) create mode 100644 packages/testkit-backend/src/controller/index.js rename packages/testkit-backend/src/{controller.js => controller/interface.js} (100%) rename packages/testkit-backend/src/{node.controller.js => controller/local.js} (86%) diff --git a/packages/testkit-backend/src/channel/index.js b/packages/testkit-backend/src/channel/index.js index 64d0ba18a..10a5e696a 100644 --- a/packages/testkit-backend/src/channel/index.js +++ b/packages/testkit-backend/src/channel/index.js @@ -1,7 +1,7 @@ -import Channel from "./abstract" +import Channel from "./interface" import SocketChannel from "./socket" export default Channel export { SocketChannel -} \ No newline at end of file +} diff --git a/packages/testkit-backend/src/channel/abstract.js b/packages/testkit-backend/src/channel/interface.js similarity index 99% rename from packages/testkit-backend/src/channel/abstract.js rename to packages/testkit-backend/src/channel/interface.js index 79e4be20c..10c1f456c 100644 --- a/packages/testkit-backend/src/channel/abstract.js +++ b/packages/testkit-backend/src/channel/interface.js @@ -18,4 +18,4 @@ export default class Channel extends EventEmitter { this.writeResponse(contextId, { name: 'BackendError', data: { msg: error } }) } -} \ No newline at end of file +} diff --git a/packages/testkit-backend/src/controller/index.js b/packages/testkit-backend/src/controller/index.js new file mode 100644 index 000000000..c21b86f9e --- /dev/null +++ b/packages/testkit-backend/src/controller/index.js @@ -0,0 +1,7 @@ +import Controller from './interface' +import LocalController from './local' + +export default Controller +export { + LocalController +} diff --git a/packages/testkit-backend/src/controller.js b/packages/testkit-backend/src/controller/interface.js similarity index 100% rename from packages/testkit-backend/src/controller.js rename to packages/testkit-backend/src/controller/interface.js diff --git a/packages/testkit-backend/src/node.controller.js b/packages/testkit-backend/src/controller/local.js similarity index 86% rename from packages/testkit-backend/src/node.controller.js rename to packages/testkit-backend/src/controller/local.js index e92a62834..3b31dc051 100644 --- a/packages/testkit-backend/src/node.controller.js +++ b/packages/testkit-backend/src/controller/local.js @@ -1,11 +1,10 @@ -import Context from './context' -import Controller from './controller' -import * as _requestHandlers from './request-handlers' +import Context from '../context' +import Controller from './interface' -export default class NodeController extends Controller { +export default class LocalController extends Controller { - constructor(requestHandlers = _requestHandlers) { + constructor(requestHandlers = {}) { super() this._requestHandlers = requestHandlers this._contexts = new Map() diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js index a0ead9a17..da8e8fa10 100644 --- a/packages/testkit-backend/src/index.js +++ b/packages/testkit-backend/src/index.js @@ -1,10 +1,11 @@ import Backend from './backend' import { SocketChannel } from './channel' -import NodeController from './node.controller' +import { LocalController } from './controller' +import * as request_handlers from './request-handlers' function main( ) { const newChannel = () => new SocketChannel(process.env.BACKEND_PORT || 9876) - const newController = () => new NodeController() + const newController = () => new LocalController(request_handlers) const backend = new Backend(newController, newChannel) backend.start() From 9197ad2a91f6d703edcfb1ce96eac12139e8b547 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 11 Nov 2021 12:24:53 +0100 Subject: [PATCH 05/12] Add WS dependency --- packages/testkit-backend/package-lock.json | 5 +++++ packages/testkit-backend/package.json | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/testkit-backend/package-lock.json b/packages/testkit-backend/package-lock.json index d57669890..6fa3e0b30 100644 --- a/packages/testkit-backend/package-lock.json +++ b/packages/testkit-backend/package-lock.json @@ -9,6 +9,11 @@ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "dev": true + }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" } } } diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index c532d7bed..66b265d4a 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -24,8 +24,9 @@ }, "homepage": "https://github.com/neo4j/neo4j-javascript-driver#readme", "dependencies": { + "neo4j-driver": "4.4.0-dev", "neo4j-driver-lite": "4.4.0-dev", - "neo4j-driver": "4.4.0-dev" + "ws": "^8.2.3" }, "devDependencies": { "esm": "^3.2.25" From 5037f8aeb4027ac72738ca52fa95156dba39ee96 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 11 Nov 2021 16:34:33 +0100 Subject: [PATCH 06/12] Implements the remote controller --- .../testkit-backend/src/channel/socket.js | 2 +- .../testkit-backend/src/controller/index.js | 4 +- .../testkit-backend/src/controller/remote.js | 112 ++++++++++++++++++ packages/testkit-backend/src/index.js | 19 ++- 4 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 packages/testkit-backend/src/controller/remote.js diff --git a/packages/testkit-backend/src/channel/socket.js b/packages/testkit-backend/src/channel/socket.js index cb173c67b..43be6cdb0 100644 --- a/packages/testkit-backend/src/channel/socket.js +++ b/packages/testkit-backend/src/channel/socket.js @@ -4,7 +4,7 @@ import { randomBytes } from 'crypto' import Protocol from './testkit-protocol' function generateRandomId () { - return randomBytes(16).toString() + return randomBytes(16).toString('hex') } export default class SocketServer extends EventEmitter { diff --git a/packages/testkit-backend/src/controller/index.js b/packages/testkit-backend/src/controller/index.js index c21b86f9e..ed23af3a8 100644 --- a/packages/testkit-backend/src/controller/index.js +++ b/packages/testkit-backend/src/controller/index.js @@ -1,7 +1,9 @@ import Controller from './interface' import LocalController from './local' +import RemoteController from './remote' export default Controller export { - LocalController + LocalController, + RemoteController } diff --git a/packages/testkit-backend/src/controller/remote.js b/packages/testkit-backend/src/controller/remote.js new file mode 100644 index 000000000..bc879f61c --- /dev/null +++ b/packages/testkit-backend/src/controller/remote.js @@ -0,0 +1,112 @@ +import Controller from "./interface" +import { WebSocketServer } from "ws" + +export default class RemoteController extends Controller { + constructor(port) { + super() + this._port = port + this._wss = null + this._ws = null + } + + start () { + if (!this._wss) { + this._wss = new WebSocketServer({ port: this._port }) + this._wss.on('connection', safeRun( ws => this._handleClientConnection(ws))) + this._wss.on('error', safeRun(error => { + console.error('[RemoteController] Server error', error) + })) + } + + } + + stop () { + if (this._ws) { + this._ws.close() + this._ws = null + } + + if(this._wss) { + this._wss.close() + this._wss = null + } + } + + onContextOpen (contextId) { + this._forwardToConnectedClient('contextOpen', contextId, { contextId }) + } + + onContextClose (contextId) { + this._forwardToConnectedClient('contextClose', contextId, { contextId }) + } + + handle (contextId, request) { + this._forwardToConnectedClient('request', contextId, request) + } + + _handleClientConnection (ws) { + if (this._ws) { + console.warn('[RemoteController] Client socket already exists, new connection will be discarded') + return + } + console.log('[RemoteController] Registering client') + + this._ws = ws + this._ws.on('message', safeRun(buffer => { + const message = JSON.parse(buffer.toString()) + console.debug('[RemoteController] Received messsage', message) + const { contextId, response } = message + this._writeResponse(contextId, response) + })) + + this._ws.on('close', () => { + console.log('[RemoteController] Client connection closed') + this._ws = null + }) + + this._ws.on('error', safeRun(error => { + console.error('[RemoteController] Client connection error', error) + })) + + console.log('[RemoteController] Client registred') + } + + _forwardToConnectedClient (messageType, contextId, data) { + if (this._ws) { + const message = { + messageType, + contextId, + data + } + + console.info(`[RemoteController] Sending message`, message) + return this._ws.send(JSON.stringify(message)) + } + console.error('[RemoteController] There is no client connected') + this._writeBackendError(contextId, 'No testkit-backend client connected') + } + + _writeResponse (contextId, response) { + console.log('> writing response', response) + + this.emit('response', { contextId, response }) + } + + _writeBackendError (contextId, msg) { + this._writeResponse(contextId, { name: 'BackendError', data: { msg: msg } }) + } + +} + + +function safeRun (func) { + return function () { + const args = [...arguments] + try { + return func.apply(null, args) + } catch (error) { + console.error(`Error in function '${func.name}' called with arguments: ${JSON.stringify(args)}.`, error) + throw error + } + } +} diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js index da8e8fa10..c0ef04200 100644 --- a/packages/testkit-backend/src/index.js +++ b/packages/testkit-backend/src/index.js @@ -1,11 +1,22 @@ import Backend from './backend' import { SocketChannel } from './channel' -import { LocalController } from './controller' -import * as request_handlers from './request-handlers' +import { LocalController, RemoteController } from './controller' +import * as REQUEST_HANDLERS from './request-handlers' function main( ) { - const newChannel = () => new SocketChannel(process.env.BACKEND_PORT || 9876) - const newController = () => new LocalController(request_handlers) + const testEnviroment = process.env.TEST_ENVIRONMENT || 'BROWSER' + const backendPort = process.env.BACKEND_PORT || 9876 + const webserverPort = process.env.WEB_SERVER_PORT || 8000 + + const newChannel = () => new SocketChannel(backendPort) + + const newController = () => { + if ( testEnviroment.toUpperCase() === 'BROWSER' ) { + return new RemoteController(webserverPort) + } + return new LocalController(REQUEST_HANDLERS) + } + const backend = new Backend(newController, newChannel) backend.start() From 8f9230be402b2b39645103c38fb9059e2452f0f8 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 11 Nov 2021 18:40:10 +0100 Subject: [PATCH 07/12] Implementing websocket channel --- packages/testkit-backend/.gitignore | 1 + packages/testkit-backend/package-lock.json | 392 ++++++++++++++++++ packages/testkit-backend/package.json | 16 +- packages/testkit-backend/public/index.html | 14 + packages/testkit-backend/rollup.config.js | 28 ++ packages/testkit-backend/src/channel/index.js | 4 +- .../testkit-backend/src/channel/websocket.js | 55 +++ .../testkit-backend/src/controller/remote.js | 20 +- packages/testkit-backend/src/index.js | 31 +- .../testkit-backend/src/request-handlers.js | 15 +- 10 files changed, 556 insertions(+), 20 deletions(-) create mode 100644 packages/testkit-backend/.gitignore create mode 100644 packages/testkit-backend/public/index.html create mode 100644 packages/testkit-backend/rollup.config.js create mode 100644 packages/testkit-backend/src/channel/websocket.js diff --git a/packages/testkit-backend/.gitignore b/packages/testkit-backend/.gitignore new file mode 100644 index 000000000..2173e574c --- /dev/null +++ b/packages/testkit-backend/.gitignore @@ -0,0 +1 @@ +public/index.js diff --git a/packages/testkit-backend/package-lock.json b/packages/testkit-backend/package-lock.json index 6fa3e0b30..2f3b1daea 100644 --- a/packages/testkit-backend/package-lock.json +++ b/packages/testkit-backend/package-lock.json @@ -4,12 +4,404 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@rollup/plugin-commonjs": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", + "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "dependencies": { + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + } + } + }, + "@rollup/plugin-inject": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.3.tgz", + "integrity": "sha512-lzMXmj0LZjd67MI+M8H9dk/oCxR0TYqYAdZ6ZOejWQLSUtud+FUPu4NCMAO8KyWWAalFo8ean7yFHCMvCNsCZw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "estree-walker": "^2.0.1", + "magic-string": "^0.25.7" + }, + "dependencies": { + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + } + } + }, + "@rollup/plugin-node-resolve": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.6.tgz", + "integrity": "sha512-sFsPDMPd4gMqnh2gS0uIxELnoRUp5kBl5knxD2EO0778G1oOJv4G1vyT2cpWz75OU2jDVcXhjVUuTAczGyFNKA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/node": { + "version": "16.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz", + "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==", + "dev": true + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, "esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "dev": true }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, + "node-static": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", + "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", + "requires": { + "colors": ">=0.6.0", + "mime": "^1.2.9", + "optimist": ">=0.3.4" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "rollup": { + "version": "2.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.59.0.tgz", + "integrity": "sha512-l7s90JQhCQ6JyZjKgo7Lq1dKh2RxatOM+Jr6a9F7WbS9WgKbocyUSeLmZl8evAse7y96Ae98L2k1cBOwWD8nHw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-inject-process-env": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-inject-process-env/-/rollup-plugin-inject-process-env-1.3.1.tgz", + "integrity": "sha512-kKDoL30IZr0wxbNVJjq+OS92RJSKRbKV6B5eNW4q3mZTFqoWDh6lHy+mPDYuuGuERFNKXkG+AKxvYqC9+DRpKQ==", + "dev": true, + "requires": { + "magic-string": "^0.25.7" + } + }, + "rollup-plugin-polyfill-node": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.7.0.tgz", + "integrity": "sha512-iJLZDfvxcQh3SpC0OiYlZG9ik26aRM29hiC2sARbAPXYunB8rzW8GtVaWuJgiCtX1hNAo/OaYvVXfPp15fMs7g==", + "dev": true, + "requires": { + "@rollup/plugin-inject": "^4.0.0" + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 66b265d4a..52167519b 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -4,8 +4,13 @@ "description": "Backend for the testkit test framework", "main": "src/main.js", "private": true, + "browser": { + "./src/controller/remote.js": "./src/controller/interface.js", + "./src/channel/socket.js": "./src/controller/interface.js" + }, "type": "module", "scripts": { + "build": "rollup src/index.js --config rollup.config.js", "start": "node -r esm src/index.js", "clean": "rm -fr node_modules" }, @@ -24,11 +29,20 @@ }, "homepage": "https://github.com/neo4j/neo4j-javascript-driver#readme", "dependencies": { + "buffer": "^6.0.3", + "events": "^3.3.0", "neo4j-driver": "4.4.0-dev", "neo4j-driver-lite": "4.4.0-dev", + "node-static": "^0.7.11", + "url": "^0.11.0", "ws": "^8.2.3" }, "devDependencies": { - "esm": "^3.2.25" + "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-node-resolve": "^13.0.6", + "esm": "^3.2.25", + "rollup": "^2.59.0", + "rollup-plugin-inject-process-env": "^1.3.1", + "rollup-plugin-polyfill-node": "^0.7.0" } } diff --git a/packages/testkit-backend/public/index.html b/packages/testkit-backend/public/index.html new file mode 100644 index 000000000..275aaed53 --- /dev/null +++ b/packages/testkit-backend/public/index.html @@ -0,0 +1,14 @@ + + + + + + + + + +

Example

+ + + + \ No newline at end of file diff --git a/packages/testkit-backend/rollup.config.js b/packages/testkit-backend/rollup.config.js new file mode 100644 index 000000000..ae5295236 --- /dev/null +++ b/packages/testkit-backend/rollup.config.js @@ -0,0 +1,28 @@ +import nodeResolve from '@rollup/plugin-node-resolve' +import commonjs from '@rollup/plugin-commonjs' +import polyfillNode from 'rollup-plugin-polyfill-node' +import injectProcessEnv from 'rollup-plugin-inject-process-env' + +export default { + input: 'src/index.js', + output: { + dir: 'public', + format: 'umd', + name: 'testkitbackend' + }, + plugins: [ + nodeResolve({ + browser: true, + preferBuiltins: false + }), + commonjs(), + polyfillNode({ + }), + injectProcessEnv({ + ...process.env, + TEST_ENVIRONMENT: 'LOCAL', + CHANNEL_TYPE: 'WEBSOCKET', + BACKEND_PORT: process.env.WEB_SERVER_PORT || 8000 + }) + ] +} diff --git a/packages/testkit-backend/src/channel/index.js b/packages/testkit-backend/src/channel/index.js index 10a5e696a..21efb084a 100644 --- a/packages/testkit-backend/src/channel/index.js +++ b/packages/testkit-backend/src/channel/index.js @@ -1,7 +1,9 @@ import Channel from "./interface" import SocketChannel from "./socket" +import WebSocketChannel from "./websocket" export default Channel export { - SocketChannel + SocketChannel, + WebSocketChannel } diff --git a/packages/testkit-backend/src/channel/websocket.js b/packages/testkit-backend/src/channel/websocket.js new file mode 100644 index 000000000..e76d2e35c --- /dev/null +++ b/packages/testkit-backend/src/channel/websocket.js @@ -0,0 +1,55 @@ +// import WebSocket from "ws" +import Channel from "./interface" + +export default class WebSocketChannel extends Channel { + + constructor(address) { + super() + this._adddress = address + this._ws = null + } + + start () { + if(!this._ws) { + this._ws = new WebSocket(this._adddress) + // this._ws.on('message', buffer => { + // const message = JSON.parse(buffer.toString()) + this._ws.onmessage = ({ data: message }) => { + console.log(message) + console.debug('[WebSocketChannel] Received messsage', message) + const { messageType, contextId, data } = JSON.parse(message) + + switch (messageType) { + case 'contextOpen': + case 'contextClose': + this.emit(messageType, data) + break + case 'request': + this.emit(messageType, { contextId, request: data }) + break + default: + console.error(`[WebSocketChannel] ${messageType} is not a valid message type`) + } + } + + // this._ws.on('close', () => this.emit('close')) + this._ws.onclose = () => this.emit('close') + } + } + + stop () { + if(this._ws) { + this._ws.close() + this._ws = null + } + } + + writeResponse (contextId, response) { + if (this._ws) { + console.debug('[WebSocketChannel] Wring response', { contextId, response }) + return this._ws.send(JSON.stringify({ contextId, response })) + } + console.error('[WebSocketChannel] Websocket is not connected') + } + +} diff --git a/packages/testkit-backend/src/controller/remote.js b/packages/testkit-backend/src/controller/remote.js index bc879f61c..3386d4528 100644 --- a/packages/testkit-backend/src/controller/remote.js +++ b/packages/testkit-backend/src/controller/remote.js @@ -1,17 +1,30 @@ import Controller from "./interface" import { WebSocketServer } from "ws" +import { createServer } from "http" +import { Server } from "node-static" export default class RemoteController extends Controller { constructor(port) { super() + this._staticServer = new Server('./public') this._port = port this._wss = null this._ws = null + this._http = null } start () { + if (!this._http) { + this._http = createServer(safeRun((request, response) => { + request.addListener('end', safeRun(() => { + this._staticServer.serve(request, response) + })).resume() + })) + + this._http.listen(this._port) + } if (!this._wss) { - this._wss = new WebSocketServer({ port: this._port }) + this._wss = new WebSocketServer({ server: this._http }) this._wss.on('connection', safeRun( ws => this._handleClientConnection(ws))) this._wss.on('error', safeRun(error => { console.error('[RemoteController] Server error', error) @@ -30,6 +43,11 @@ export default class RemoteController extends Controller { this._wss.close() this._wss = null } + + if (this._http) { + this._http.close() + this._http = null + } } onContextOpen (contextId) { diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js index c0ef04200..14512d33d 100644 --- a/packages/testkit-backend/src/index.js +++ b/packages/testkit-backend/src/index.js @@ -1,17 +1,24 @@ import Backend from './backend' -import { SocketChannel } from './channel' +import { SocketChannel, WebSocketChannel } from './channel' import { LocalController, RemoteController } from './controller' import * as REQUEST_HANDLERS from './request-handlers' function main( ) { - const testEnviroment = process.env.TEST_ENVIRONMENT || 'BROWSER' + const testEnviroment = process.env.TEST_ENVIRONMENT || 'LOCAL' + const channelType = process.env.CHANNEL_TYPE || 'SOCKET' const backendPort = process.env.BACKEND_PORT || 9876 const webserverPort = process.env.WEB_SERVER_PORT || 8000 - const newChannel = () => new SocketChannel(backendPort) + const newChannel = () => { + if ( channelType.toUpperCase() === 'WEBSOCKET' ) { + return new WebSocketChannel(new URL(`ws://localhost:${backendPort}`)) + + } + return new SocketChannel(backendPort) + } const newController = () => { - if ( testEnviroment.toUpperCase() === 'BROWSER' ) { + if ( testEnviroment.toUpperCase() === 'REMOTE' ) { return new RemoteController(webserverPort) } return new LocalController(REQUEST_HANDLERS) @@ -21,14 +28,16 @@ function main( ) { backend.start() - // cleaning up - process.on('exit', backend.stop.bind(backend)); + if (process.on) { + // cleaning up + process.on('exit', backend.stop.bind(backend)); - // Capturing signals - process.on('SIGINT', process.exit.bind(process)); - process.on('SIGUSR1', process.exit.bind(process)); - process.on('SIGUSR2', process.exit.bind(process)); - process.on('uncaughtException', process.exit.bind(process)); + // Capturing signals + process.on('SIGINT', process.exit.bind(process)); + process.on('SIGUSR1', process.exit.bind(process)); + process.on('SIGUSR2', process.exit.bind(process)); + process.on('uncaughtException', process.exit.bind(process)); + } } main() diff --git a/packages/testkit-backend/src/request-handlers.js b/packages/testkit-backend/src/request-handlers.js index 0b3064c7d..857bf4a5e 100644 --- a/packages/testkit-backend/src/request-handlers.js +++ b/packages/testkit-backend/src/request-handlers.js @@ -5,13 +5,16 @@ import { shouldRunTest } from './skipped-tests' import tls from 'tls' const SUPPORTED_TLS = (() => { - 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)}`) + 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 result; + return []; })(); export function NewDriver (context, data, { writeResponse }) { From de2c52b27fc4074320bd6a6addf32ae159757296 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Fri, 12 Nov 2021 12:06:30 +0100 Subject: [PATCH 08/12] docs --- packages/testkit-backend/package-lock.json | 43 ------------------- packages/testkit-backend/package.json | 5 +-- packages/testkit-backend/src/backend.js | 4 +- packages/testkit-backend/src/channel/index.js | 10 ++++- .../testkit-backend/src/channel/interface.js | 9 ++++ .../testkit-backend/src/channel/socket.js | 9 +++- .../testkit-backend/src/channel/websocket.js | 9 ++-- .../testkit-backend/src/controller/index.js | 6 +++ .../src/controller/interface.js | 10 ++++- .../testkit-backend/src/controller/local.js | 12 ++++-- .../testkit-backend/src/controller/remote.js | 12 +++++- packages/testkit-backend/src/index.js | 3 ++ 12 files changed, 68 insertions(+), 64 deletions(-) diff --git a/packages/testkit-backend/package-lock.json b/packages/testkit-backend/package-lock.json index 2f3b1daea..219d83d0c 100644 --- a/packages/testkit-backend/package-lock.json +++ b/packages/testkit-backend/package-lock.json @@ -98,11 +98,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -113,15 +108,6 @@ "concat-map": "0.0.1" } }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -163,11 +149,6 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -210,11 +191,6 @@ "function-bind": "^1.1.1" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -329,16 +305,6 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -382,15 +348,6 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 52167519b..843323a5b 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -12,7 +12,7 @@ "scripts": { "build": "rollup src/index.js --config rollup.config.js", "start": "node -r esm src/index.js", - "clean": "rm -fr node_modules" + "clean": "rm -fr node_modules public/index.js" }, "repository": { "type": "git", @@ -29,12 +29,9 @@ }, "homepage": "https://github.com/neo4j/neo4j-javascript-driver#readme", "dependencies": { - "buffer": "^6.0.3", - "events": "^3.3.0", "neo4j-driver": "4.4.0-dev", "neo4j-driver-lite": "4.4.0-dev", "node-static": "^0.7.11", - "url": "^0.11.0", "ws": "^8.2.3" }, "devDependencies": { diff --git a/packages/testkit-backend/src/backend.js b/packages/testkit-backend/src/backend.js index 5c59bd1ed..f1f8983cd 100644 --- a/packages/testkit-backend/src/backend.js +++ b/packages/testkit-backend/src/backend.js @@ -18,8 +18,8 @@ export default class Backend { this._channel.writeResponse(contextId, response) }) - this._channel.on('contextOpen', ({ contextId }) => this._controller.onContextOpen(contextId)) - this._channel.on('contextClose', ({ contextId }) => this._controller.onContextClose(contextId)) + this._channel.on('contextOpen', ({ contextId }) => this._controller.openContext(contextId)) + this._channel.on('contextClose', ({ contextId }) => this._controller.closeContext(contextId)) this._channel.on('request', ({ contextId, request }) => { try { diff --git a/packages/testkit-backend/src/channel/index.js b/packages/testkit-backend/src/channel/index.js index 21efb084a..61788f219 100644 --- a/packages/testkit-backend/src/channel/index.js +++ b/packages/testkit-backend/src/channel/index.js @@ -1,7 +1,15 @@ import Channel from "./interface" import SocketChannel from "./socket" import WebSocketChannel from "./websocket" - +/** + * Channels are the piece of code responsible for communicate with tesktit. + * + * {@link SocketChannel} is a server socket implementation meant to be used to talk directly to the + * testkit server. + * + * {@link WebSocketChannel} is a client implementation used for connection to other testkit-backend for receiving + * messages. + */ export default Channel export { SocketChannel, diff --git a/packages/testkit-backend/src/channel/interface.js b/packages/testkit-backend/src/channel/interface.js index 10c1f456c..f2d619070 100644 --- a/packages/testkit-backend/src/channel/interface.js +++ b/packages/testkit-backend/src/channel/interface.js @@ -1,5 +1,14 @@ import { EventEmitter } from "events" +/** + * Defines the interface used for receiving commands form the teskit. + * + * This is a thin layer only responsilbe for receive messages and send messages to testkit. + * + * @event contextOpen This event is triggered when a new testkit client start its work. + * @event contextClose This event is triggered when an existing client finish it work + * @event request Thiis event is triggered when the channel receives a request + */ export default class Channel extends EventEmitter { start () { diff --git a/packages/testkit-backend/src/channel/socket.js b/packages/testkit-backend/src/channel/socket.js index 43be6cdb0..a818d73cc 100644 --- a/packages/testkit-backend/src/channel/socket.js +++ b/packages/testkit-backend/src/channel/socket.js @@ -1,4 +1,4 @@ -import { EventEmitter } from 'events' +import Channel from './interface' import net from 'net' import { randomBytes } from 'crypto' import Protocol from './testkit-protocol' @@ -7,7 +7,12 @@ function generateRandomId () { return randomBytes(16).toString('hex') } -export default class SocketServer extends EventEmitter { +/** + * This is communication channel handles the direct communcation with testkit using it own protocol. + * + * This implementatio is meant to be runned in the NodeJS, it doesn't support Browser. + */ +export default class SocketChannel extends Channel { constructor(port, newProtocol = stream => new Protocol(stream), newId = generateRandomId ) { super() this._newProtocol = newProtocol diff --git a/packages/testkit-backend/src/channel/websocket.js b/packages/testkit-backend/src/channel/websocket.js index e76d2e35c..cbc953236 100644 --- a/packages/testkit-backend/src/channel/websocket.js +++ b/packages/testkit-backend/src/channel/websocket.js @@ -1,6 +1,10 @@ -// import WebSocket from "ws" import Channel from "./interface" +/** + * This communication channels is meant to connect to other instances of the `testkit-backend` for receiving its events. + * + * This channel is only supported in browsers since it depends on WebSocket client be avaiable globaly. + */ export default class WebSocketChannel extends Channel { constructor(address) { @@ -12,8 +16,6 @@ export default class WebSocketChannel extends Channel { start () { if(!this._ws) { this._ws = new WebSocket(this._adddress) - // this._ws.on('message', buffer => { - // const message = JSON.parse(buffer.toString()) this._ws.onmessage = ({ data: message }) => { console.log(message) console.debug('[WebSocketChannel] Received messsage', message) @@ -32,7 +34,6 @@ export default class WebSocketChannel extends Channel { } } - // this._ws.on('close', () => this.emit('close')) this._ws.onclose = () => this.emit('close') } } diff --git a/packages/testkit-backend/src/controller/index.js b/packages/testkit-backend/src/controller/index.js index ed23af3a8..4cdc654a6 100644 --- a/packages/testkit-backend/src/controller/index.js +++ b/packages/testkit-backend/src/controller/index.js @@ -2,6 +2,12 @@ import Controller from './interface' import LocalController from './local' import RemoteController from './remote' +/** + * Controllers are piece of code responsabile for redicting the requests to the correct handler. + * + * {@link LocalController} delegates the requests to be handled by local handlers. + * {@link RemoteController} delegates the request to be handled by remote clients by forwarding the requests over websockets. + */ export default Controller export { LocalController, diff --git a/packages/testkit-backend/src/controller/interface.js b/packages/testkit-backend/src/controller/interface.js index e6876e8c9..fc833bef4 100644 --- a/packages/testkit-backend/src/controller/interface.js +++ b/packages/testkit-backend/src/controller/interface.js @@ -1,5 +1,11 @@ import { EventEmitter } from 'events' +/** + * Controller is the unit responsabile for redirecting the requests to the correct handler and managing the + * creation and destruction of the request contexts. + * + * @event response Event triggered whith response to the request handled. + */ export default class Controller extends EventEmitter { start () { @@ -10,11 +16,11 @@ export default class Controller extends EventEmitter { } - onContextOpen(contextId) { + openContext (contextId) { throw new Error('not implemented') } - onContextClose(contextId) { + closeContext (contextId) { throw new Error('not implemented') } diff --git a/packages/testkit-backend/src/controller/local.js b/packages/testkit-backend/src/controller/local.js index 3b31dc051..6a1eeb8f1 100644 --- a/packages/testkit-backend/src/controller/local.js +++ b/packages/testkit-backend/src/controller/local.js @@ -2,6 +2,11 @@ import Context from '../context' import Controller from './interface' +/** + * Local controller handles locally the requests by redirecting to the correct request handler/service. + * + * This controller when testing browser and locally. + */ export default class LocalController extends Controller { constructor(requestHandlers = {}) { @@ -10,16 +15,15 @@ export default class LocalController extends Controller { this._contexts = new Map() } - onContextOpen(contextId) { + openContext (contextId) { this._contexts.set(contextId, new Context()) } - onContextClose(contextId) { + closeContext (contextId) { this._contexts.delete(contextId) } - - handle(contextId, { name, data }) { + handle (contextId, { name, data }) { if (!this._contexts.has(contextId)) { throw new Error(`Context ${contextId} does not exist`) } else if (!(name in this._requestHandlers)) { diff --git a/packages/testkit-backend/src/controller/remote.js b/packages/testkit-backend/src/controller/remote.js index 3386d4528..34935611c 100644 --- a/packages/testkit-backend/src/controller/remote.js +++ b/packages/testkit-backend/src/controller/remote.js @@ -3,6 +3,14 @@ import { WebSocketServer } from "ws" import { createServer } from "http" import { Server } from "node-static" +/** + * Remote controller handles the requests by send it to a remote client. + * + * This controller only support only on client connected at the same time and it will + * give an error response whenever any request came and it doesn't have any client connected. + * + * This controller could only be used in Node since it depends on {@link createServer}, {@link WebSocketServer} and {@link Server} + */ export default class RemoteController extends Controller { constructor(port) { super() @@ -50,11 +58,11 @@ export default class RemoteController extends Controller { } } - onContextOpen (contextId) { + openContext (contextId) { this._forwardToConnectedClient('contextOpen', contextId, { contextId }) } - onContextClose (contextId) { + closeContext (contextId) { this._forwardToConnectedClient('contextClose', contextId, { contextId }) } diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js index 14512d33d..d78433112 100644 --- a/packages/testkit-backend/src/index.js +++ b/packages/testkit-backend/src/index.js @@ -3,6 +3,9 @@ import { SocketChannel, WebSocketChannel } from './channel' import { LocalController, RemoteController } from './controller' import * as REQUEST_HANDLERS from './request-handlers' +/** + * Responsabile for configure and run the backend server. + */ function main( ) { const testEnviroment = process.env.TEST_ENVIRONMENT || 'LOCAL' const channelType = process.env.CHANNEL_TYPE || 'SOCKET' From 8bf951720beb63baff9dd7d712ceb3ac87a58721 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Fri, 12 Nov 2021 16:05:45 +0100 Subject: [PATCH 09/12] tk backend --- packages/testkit-backend/package.json | 3 ++- testkit/backend.py | 21 ++++++++++++++++++-- testkit/common.py | 28 +++++++++++++++++++++------ testkit/integration.py | 15 ++++---------- testkit/stress.py | 13 +++++++------ 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 843323a5b..8e68ae0fd 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -12,7 +12,8 @@ "scripts": { "build": "rollup src/index.js --config rollup.config.js", "start": "node -r esm src/index.js", - "clean": "rm -fr node_modules public/index.js" + "clean": "rm -fr node_modules public/index.js", + "prepare": "npm run build" }, "repository": { "type": "git", diff --git a/testkit/backend.py b/testkit/backend.py index 949022814..1b428a8d7 100644 --- a/testkit/backend.py +++ b/testkit/backend.py @@ -3,8 +3,25 @@ Assumes driver and backend has been built. Responsible for starting the test backend. """ -from common import run_in_driver_repo +from common import open_proccess_in_driver_repo, is_browser import os +import time if __name__ == "__main__": - run_in_driver_repo(["npm", "run", "start-testkit-backend"], env=os.environ) + print("starting backend") + if is_browser(): + print("Testkit should test browser") + os.environ["TEST_ENVIRONMENT"] = "REMOTE" + print("openning firefox") + + print("npm run start-testkit-backend") + with open_proccess_in_driver_repo([ + "npm", "run", "start-testkit-backend" + ], env=os.environ) as backend: + if (is_browser()): + time.sleep(5) + with open_proccess_in_driver_repo([ + "firefox", "-headless", "http://localhost:8000" + ]) as firefox: + firefox.wait() + backend.wait() diff --git a/testkit/common.py b/testkit/common.py index 611d84c11..c1d6e2798 100644 --- a/testkit/common.py +++ b/testkit/common.py @@ -8,10 +8,17 @@ DRIVER_REPO = "/home/driver/repo/" -def run(args, env=None, cwd=None): +def is_enabled(value): + return value.lower() in ( + "y", "yes", "t", "true", "1", "on" + ) + + +def run(args, env=None, cwd=None, + stderr=subprocess.STDOUT, stdout=None, check=True): subprocess.run( - args, universal_newlines=True, stderr=subprocess.STDOUT, - check=True, env=env, cwd=cwd) + args, universal_newlines=True, stderr=stderr, stdout=stdout, + check=check, env=env, cwd=cwd) def run_in(cwd): @@ -20,9 +27,18 @@ def _runIn(args, env=None): return _runIn -def run_in_driver_repo(args, env=None): - return run(args, env, DRIVER_REPO) +def run_in_driver_repo(args, env=None, + stderr=subprocess.STDOUT, stdout=None, check=True): + return run(args, env, DRIVER_REPO, stdout=stdout, stderr=stderr, check=check) + + +def open_proccess_in_driver_repo(args, env=None): + return subprocess.Popen(args, cwd=DRIVER_REPO, env=env) def is_lite(): - return os.environ.get("TEST_DRIVER_LITE", "False").upper() in ["TRUE", "1"] + return is_enabled(os.environ.get("TEST_DRIVER_LITE", "false")) + + +def is_browser(): + return is_enabled(os.environ.get("TEST_DRIVER_BROWSER", "false")) diff --git a/testkit/integration.py b/testkit/integration.py index 3c1b3465e..af8821ec7 100644 --- a/testkit/integration.py +++ b/testkit/integration.py @@ -1,13 +1,6 @@ import os -from common import run_in_driver_repo, is_lite - - -def should_test_browser(): - return os.environ.get("TEST_DRIVER_SKIP_BROWSER", "false").lower() not in ( - "y", "yes", "t", "true", "1", "on" - ) - +from common import run_in_driver_repo, is_lite, is_browser if __name__ == "__main__": os.environ["TEST_NEO4J_IPV6_ENABLED"] = "False" @@ -17,7 +10,7 @@ def should_test_browser(): else: ignore = "--ignore=neo4j-driver-lite" - run_in_driver_repo(["npm", "run", "test::integration", "--", ignore]) - - if should_test_browser(): + if is_browser(): run_in_driver_repo(["npm", "run", "test::browser", "--", ignore]) + else: + run_in_driver_repo(["npm", "run", "test::integration", "--", ignore]) diff --git a/testkit/stress.py b/testkit/stress.py index 77fac8dab..45c379f9b 100644 --- a/testkit/stress.py +++ b/testkit/stress.py @@ -1,5 +1,5 @@ import os -from common import run_in_driver_repo, is_lite +from common import run_in_driver_repo, is_lite, is_browser if __name__ == "__main__": @@ -7,9 +7,10 @@ os.environ["RUNNING_TIME_IN_SECONDS"] = \ os.environ.get("TEST_NEO4J_STRESS_DURATION", 0) - if is_lite(): - ignore = "--ignore=neo4j-driver" - else: - ignore = "--ignore=neo4j-driver-lite" + if not is_browser(): + if is_lite(): + ignore = "--ignore=neo4j-driver" + else: + ignore = "--ignore=neo4j-driver-lite" - run_in_driver_repo(["npm", "run", "test::stress", "--", ignore]) + run_in_driver_repo(["npm", "run", "test::stress", "--", ignore]) From 54119c6ec04c647df4462f907811ac291add607e Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Mon, 15 Nov 2021 11:21:02 +0100 Subject: [PATCH 10/12] Fix serialization --- packages/testkit-backend/src/channel/websocket.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/testkit-backend/src/channel/websocket.js b/packages/testkit-backend/src/channel/websocket.js index cbc953236..42b0ad009 100644 --- a/packages/testkit-backend/src/channel/websocket.js +++ b/packages/testkit-backend/src/channel/websocket.js @@ -48,9 +48,15 @@ export default class WebSocketChannel extends Channel { writeResponse (contextId, response) { if (this._ws) { console.debug('[WebSocketChannel] Wring response', { contextId, response }) - return this._ws.send(JSON.stringify({ contextId, response })) + return this._ws.send(this._serialize({ contextId, response })) } console.error('[WebSocketChannel] Websocket is not connected') } + _serialize (val) { + return JSON.stringify(val, (_, value) => + typeof value === 'bigint' ? `${value}n` : value + ) + } + } From c7c72f1e64e58a76dd2ee790539e518e2d87a529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Barc=C3=A9los?= Date: Wed, 17 Nov 2021 12:11:13 -0300 Subject: [PATCH 11/12] Apply suggestions from code review Co-authored-by: Robsdedude --- packages/testkit-backend/src/channel/index.js | 2 +- packages/testkit-backend/src/channel/interface.js | 10 +++++----- packages/testkit-backend/src/channel/socket.js | 4 ++-- packages/testkit-backend/src/channel/websocket.js | 6 +++--- packages/testkit-backend/src/controller/index.js | 4 ++-- packages/testkit-backend/src/controller/interface.js | 2 +- packages/testkit-backend/src/controller/local.js | 4 ++-- packages/testkit-backend/src/controller/remote.js | 8 ++++---- packages/testkit-backend/src/index.js | 2 +- testkit/backend.py | 9 ++++++--- testkit/integration.py | 6 +++++- testkit/stress.py | 6 +++++- 12 files changed, 37 insertions(+), 26 deletions(-) diff --git a/packages/testkit-backend/src/channel/index.js b/packages/testkit-backend/src/channel/index.js index 61788f219..3f6350362 100644 --- a/packages/testkit-backend/src/channel/index.js +++ b/packages/testkit-backend/src/channel/index.js @@ -2,7 +2,7 @@ import Channel from "./interface" import SocketChannel from "./socket" import WebSocketChannel from "./websocket" /** - * Channels are the piece of code responsible for communicate with tesktit. + * Channels are the pieces of code responsible for communicating with testkit. * * {@link SocketChannel} is a server socket implementation meant to be used to talk directly to the * testkit server. diff --git a/packages/testkit-backend/src/channel/interface.js b/packages/testkit-backend/src/channel/interface.js index f2d619070..9cadfdea1 100644 --- a/packages/testkit-backend/src/channel/interface.js +++ b/packages/testkit-backend/src/channel/interface.js @@ -1,13 +1,13 @@ import { EventEmitter } from "events" /** - * Defines the interface used for receiving commands form the teskit. + * Defines the interface used for receiving commands form teskit. * - * This is a thin layer only responsilbe for receive messages and send messages to testkit. + * This is a thin layer only responsible for receiving and sending messages from and to testkit. * - * @event contextOpen This event is triggered when a new testkit client start its work. - * @event contextClose This event is triggered when an existing client finish it work - * @event request Thiis event is triggered when the channel receives a request + * @event contextOpen This event is triggered when a new testkit client starts its work. + * @event contextClose This event is triggered when an existing client finishes it work + * @event request This event is triggered when the channel receives a request */ export default class Channel extends EventEmitter { diff --git a/packages/testkit-backend/src/channel/socket.js b/packages/testkit-backend/src/channel/socket.js index a818d73cc..37e440688 100644 --- a/packages/testkit-backend/src/channel/socket.js +++ b/packages/testkit-backend/src/channel/socket.js @@ -8,9 +8,9 @@ function generateRandomId () { } /** - * This is communication channel handles the direct communcation with testkit using it own protocol. + * This is communication channel handles the direct communication with TestKit using its protocol. * - * This implementatio is meant to be runned in the NodeJS, it doesn't support Browser. + * This implementation is meant to be run in NodeJS, it doesn't support Browser. */ export default class SocketChannel extends Channel { constructor(port, newProtocol = stream => new Protocol(stream), newId = generateRandomId ) { diff --git a/packages/testkit-backend/src/channel/websocket.js b/packages/testkit-backend/src/channel/websocket.js index 42b0ad009..4c8281dfa 100644 --- a/packages/testkit-backend/src/channel/websocket.js +++ b/packages/testkit-backend/src/channel/websocket.js @@ -1,9 +1,9 @@ import Channel from "./interface" /** - * This communication channels is meant to connect to other instances of the `testkit-backend` for receiving its events. + * This communication channel is meant to connect to other instances of the `testkit-backend` for receiving its events. * - * This channel is only supported in browsers since it depends on WebSocket client be avaiable globaly. + * This channel is only supported in browsers since it depends on WebSocket client to be available globally. */ export default class WebSocketChannel extends Channel { @@ -47,7 +47,7 @@ export default class WebSocketChannel extends Channel { writeResponse (contextId, response) { if (this._ws) { - console.debug('[WebSocketChannel] Wring response', { contextId, response }) + console.debug('[WebSocketChannel] Writing response', { contextId, response }) return this._ws.send(this._serialize({ contextId, response })) } console.error('[WebSocketChannel] Websocket is not connected') diff --git a/packages/testkit-backend/src/controller/index.js b/packages/testkit-backend/src/controller/index.js index 4cdc654a6..6fc687335 100644 --- a/packages/testkit-backend/src/controller/index.js +++ b/packages/testkit-backend/src/controller/index.js @@ -3,10 +3,10 @@ import LocalController from './local' import RemoteController from './remote' /** - * Controllers are piece of code responsabile for redicting the requests to the correct handler. + * Controllers are pieces of code responsible for redirecting requests to the correct handler. * * {@link LocalController} delegates the requests to be handled by local handlers. - * {@link RemoteController} delegates the request to be handled by remote clients by forwarding the requests over websockets. + * {@link RemoteController} delegates the requests to be handled by remote clients by forwarding the requests over websockets. */ export default Controller export { diff --git a/packages/testkit-backend/src/controller/interface.js b/packages/testkit-backend/src/controller/interface.js index fc833bef4..3de0cb961 100644 --- a/packages/testkit-backend/src/controller/interface.js +++ b/packages/testkit-backend/src/controller/interface.js @@ -1,7 +1,7 @@ import { EventEmitter } from 'events' /** - * Controller is the unit responsabile for redirecting the requests to the correct handler and managing the + * Controller is the unit responsible for redirecting the requests to the correct handler and managing the * creation and destruction of the request contexts. * * @event response Event triggered whith response to the request handled. diff --git a/packages/testkit-backend/src/controller/local.js b/packages/testkit-backend/src/controller/local.js index 6a1eeb8f1..aed4a4a80 100644 --- a/packages/testkit-backend/src/controller/local.js +++ b/packages/testkit-backend/src/controller/local.js @@ -3,9 +3,9 @@ import Controller from './interface' /** - * Local controller handles locally the requests by redirecting to the correct request handler/service. + * Local controller handles the requests locally by redirecting them to the correct request handler/service. * - * This controller when testing browser and locally. + * This controller is used when testing browser and locally. */ export default class LocalController extends Controller { diff --git a/packages/testkit-backend/src/controller/remote.js b/packages/testkit-backend/src/controller/remote.js index 34935611c..fc13fedf1 100644 --- a/packages/testkit-backend/src/controller/remote.js +++ b/packages/testkit-backend/src/controller/remote.js @@ -4,12 +4,12 @@ import { createServer } from "http" import { Server } from "node-static" /** - * Remote controller handles the requests by send it to a remote client. + * RemoteController handles the requests by sending them a remote client. * - * This controller only support only on client connected at the same time and it will - * give an error response whenever any request came and it doesn't have any client connected. + * This controller requires a client to be connected. Otherwise, it will reply with a BackendError + * to every incoming request. * - * This controller could only be used in Node since it depends on {@link createServer}, {@link WebSocketServer} and {@link Server} + * This controller can only be used in Node since it depends on {@link createServer}, {@link WebSocketServer} and {@link Server} */ export default class RemoteController extends Controller { constructor(port) { diff --git a/packages/testkit-backend/src/index.js b/packages/testkit-backend/src/index.js index d78433112..e4f3928f7 100644 --- a/packages/testkit-backend/src/index.js +++ b/packages/testkit-backend/src/index.js @@ -4,7 +4,7 @@ import { LocalController, RemoteController } from './controller' import * as REQUEST_HANDLERS from './request-handlers' /** - * Responsabile for configure and run the backend server. + * Responsible for configure and run the backend server. */ function main( ) { const testEnviroment = process.env.TEST_ENVIRONMENT || 'LOCAL' diff --git a/testkit/backend.py b/testkit/backend.py index 1b428a8d7..304f08a57 100644 --- a/testkit/backend.py +++ b/testkit/backend.py @@ -3,7 +3,10 @@ Assumes driver and backend has been built. Responsible for starting the test backend. """ -from common import open_proccess_in_driver_repo, is_browser +from common import ( + open_proccess_in_driver_repo, + is_browser, +) import os import time @@ -12,14 +15,14 @@ if is_browser(): print("Testkit should test browser") os.environ["TEST_ENVIRONMENT"] = "REMOTE" - print("openning firefox") print("npm run start-testkit-backend") with open_proccess_in_driver_repo([ - "npm", "run", "start-testkit-backend" + "npm", "run", "start-testkit-backend" ], env=os.environ) as backend: if (is_browser()): time.sleep(5) + print("openning firefox") with open_proccess_in_driver_repo([ "firefox", "-headless", "http://localhost:8000" ]) as firefox: diff --git a/testkit/integration.py b/testkit/integration.py index af8821ec7..1af24054e 100644 --- a/testkit/integration.py +++ b/testkit/integration.py @@ -1,6 +1,10 @@ import os -from common import run_in_driver_repo, is_lite, is_browser +from common import ( + is_browser, + is_lite, + run_in_driver_repo, +) if __name__ == "__main__": os.environ["TEST_NEO4J_IPV6_ENABLED"] = "False" diff --git a/testkit/stress.py b/testkit/stress.py index 45c379f9b..7481e6bae 100644 --- a/testkit/stress.py +++ b/testkit/stress.py @@ -1,5 +1,9 @@ import os -from common import run_in_driver_repo, is_lite, is_browser +from common import ( + is_browser, + is_lite, + run_in_driver_repo, +) if __name__ == "__main__": From ab9c6fecf38a1bb6a40751688cecdc15fbcd9c99 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Wed, 17 Nov 2021 17:02:56 +0100 Subject: [PATCH 12/12] Redirect stdout and stderr to system --- testkit/common.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/testkit/common.py b/testkit/common.py index c1d6e2798..a6e58adff 100644 --- a/testkit/common.py +++ b/testkit/common.py @@ -3,6 +3,7 @@ """ import subprocess import os +import sys DRIVER_REPO = "/home/driver/repo/" @@ -14,10 +15,9 @@ def is_enabled(value): ) -def run(args, env=None, cwd=None, - stderr=subprocess.STDOUT, stdout=None, check=True): +def run(args, env=None, cwd=None, check=True): subprocess.run( - args, universal_newlines=True, stderr=stderr, stdout=stdout, + args, universal_newlines=True, stderr=sys.stderr, stdout=sys.stdout, check=check, env=env, cwd=cwd) @@ -27,13 +27,13 @@ def _runIn(args, env=None): return _runIn -def run_in_driver_repo(args, env=None, - stderr=subprocess.STDOUT, stdout=None, check=True): - return run(args, env, DRIVER_REPO, stdout=stdout, stderr=stderr, check=check) +def run_in_driver_repo(args, env=None, check=True): + return run(args, env, DRIVER_REPO, check=check) def open_proccess_in_driver_repo(args, env=None): - return subprocess.Popen(args, cwd=DRIVER_REPO, env=env) + return subprocess.Popen(args, cwd=DRIVER_REPO, env=env, stderr=sys.stderr, + stdout=sys.stdout) def is_lite():