From bca1e28f5ade0502245785ad0bcd46534d7039ac Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 12:42:59 +1000 Subject: [PATCH 01/27] uplift startTls code to be compatible with current bun --- lib/connection.js | 89 +++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 65 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index 2a33c5aefc..9b191bc79d 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -354,49 +354,51 @@ class Connection extends EventEmitter { maxVersion: this.config.ssl.maxVersion }); const rejectUnauthorized = this.config.ssl.rejectUnauthorized; - const verifyIdentity = this.config.ssl.verifyIdentity; - const host = this.config.host; + const verifyIdentity = true; //this.config.ssl.verifyIdentity; + const servername = this.config.host let secureEstablished = false; - const secureSocket = new Tls.TLSSocket(this.stream, { - rejectUnauthorized: rejectUnauthorized, - requestCert: true, - secureContext: secureContext, - isServer: false + this.stream.removeAllListeners('data'); + const secureSocket = Tls.connect({ + rejectUnauthorized, + requestCert: rejectUnauthorized, + secureContext, + isServer: false, + socket: this.stream, + servername }); - if (typeof host === 'string') { - secureSocket.setServername(host); - } + // error handler for secure socket - secureSocket.on('_tlsError', err => { + secureSocket.on('error', err => { if (secureEstablished) { this._handleNetworkError(err); } else { onSecure(err); } }); - secureSocket.on('secure', () => { + secureSocket.on('secureConnect', () => { secureEstablished = true; - let callbackValue = null; if (rejectUnauthorized) { - callbackValue = secureSocket.ssl.verifyError() - if (!callbackValue && typeof host === 'string' && verifyIdentity) { - const cert = secureSocket.ssl.getPeerCertificate(true); - callbackValue = Tls.checkServerIdentity(host, cert) + if (typeof servername === 'string' && verifyIdentity) { + const cert = secureSocket.getPeerCertificate(true); + const serverIdentityCheckError = Tls.checkServerIdentity(servername, cert); + if (serverIdentityCheckError) { + onSecure(serverIdentityCheckError); + return; + } } } - onSecure(callbackValue); + onSecure(); }); secureSocket.on('data', data => { this.packetParser.execute(data); }); this.write = buffer => { - secureSocket.write(buffer); + return secureSocket.write(buffer); }; - // start TLS communications - secureSocket._start(); } + /* pipe() { if (this.stream instanceof Net.Stream) { this.stream.ondata = (data, start, end) => { @@ -412,6 +414,7 @@ class Connection extends EventEmitter { }); } } + */ protocolError(message, code) { // Starting with MySQL 8.0.24, if the client closes the connection @@ -948,48 +951,4 @@ class Connection extends EventEmitter { } } -if (Tls.TLSSocket) { - // not supported -} else { - Connection.prototype.startTLS = function _startTLS(onSecure) { - if (this.config.debug) { - // eslint-disable-next-line no-console - console.log('Upgrading connection to TLS'); - } - const crypto = require('crypto'); - const config = this.config; - const stream = this.stream; - const rejectUnauthorized = this.config.ssl.rejectUnauthorized; - const credentials = crypto.createCredentials({ - key: config.ssl.key, - cert: config.ssl.cert, - passphrase: config.ssl.passphrase, - ca: config.ssl.ca, - ciphers: config.ssl.ciphers - }); - const securePair = Tls.createSecurePair( - credentials, - false, - true, - rejectUnauthorized - ); - - if (stream.ondata) { - stream.ondata = null; - } - stream.removeAllListeners('data'); - stream.pipe(securePair.encrypted); - securePair.encrypted.pipe(stream); - securePair.cleartext.on('data', data => { - this.packetParser.execute(data); - }); - this.write = function(buffer) { - securePair.cleartext.write(buffer); - }; - securePair.on('secure', () => { - onSecure(rejectUnauthorized ? securePair.ssl.verifyError() : null); - }); - }; -} - module.exports = Connection; From f4fb55e07734bc9cc90f81c89e1bc08f3872bae9 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 13:05:49 +1000 Subject: [PATCH 02/27] more tls refactoring --- lib/connection.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index 9b191bc79d..5a5470c91c 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -354,7 +354,7 @@ class Connection extends EventEmitter { maxVersion: this.config.ssl.maxVersion }); const rejectUnauthorized = this.config.ssl.rejectUnauthorized; - const verifyIdentity = true; //this.config.ssl.verifyIdentity; + const verifyIdentity = this.config.ssl.verifyIdentity; const servername = this.config.host let secureEstablished = false; @@ -366,17 +366,7 @@ class Connection extends EventEmitter { isServer: false, socket: this.stream, servername - }); - - // error handler for secure socket - secureSocket.on('error', err => { - if (secureEstablished) { - this._handleNetworkError(err); - } else { - onSecure(err); - } - }); - secureSocket.on('secureConnect', () => { + }, () => { secureEstablished = true; if (rejectUnauthorized) { if (typeof servername === 'string' && verifyIdentity) { @@ -390,6 +380,14 @@ class Connection extends EventEmitter { } onSecure(); }); + // error handler for secure socket + secureSocket.on('error', err => { + if (secureEstablished) { + this._handleNetworkError(err); + } else { + onSecure(err); + } + }); secureSocket.on('data', data => { this.packetParser.execute(data); }); From 69e3b2fc9d16178370ee389a1e14752c49d682c6 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 13:07:52 +1000 Subject: [PATCH 03/27] lint --- lib/connection.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index 5a5470c91c..e5cb24f043 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -391,9 +391,7 @@ class Connection extends EventEmitter { secureSocket.on('data', data => { this.packetParser.execute(data); }); - this.write = buffer => { - return secureSocket.write(buffer); - }; + this.write = buffer => secureSocket.write(buffer); } /* From e52b5d0318ba6765542eca34c97e23f3484552af Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 13:37:53 +1000 Subject: [PATCH 04/27] ci: enable tls in bun matrix --- .github/workflows/ci-bun.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index 14ddb03faa..990be809b6 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -20,10 +20,10 @@ jobs: strategy: fail-fast: false matrix: - bun-version: [0.5.1] + bun-version: [0.6.13] mysql-version: ["mysql:5.7", "mysql:8.0.18", "mysql:8.0.22"] use-compression: [0] - use-tls: [0] + use-tls: [0,1] name: Bun ${{ matrix.bun-version }} - DB ${{ matrix.mysql-version }} - SSL=${{matrix.use-tls}} Compression=${{matrix.use-compression}} From 607a66d6ece1ebafb5e0ba87fa68af5d2f81d823 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 14:21:23 +1000 Subject: [PATCH 05/27] fix ssl tests --- .github/workflows/ci-bun.yml | 2 +- test/common.js | 3 ++- test/integration/connection/test-select-ssl.js | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 test/integration/connection/test-select-ssl.js diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index 990be809b6..7e467f3c4c 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -59,4 +59,4 @@ jobs: - name: Run tests # todo: run full test suite once test createServer is implemented using Bun.listen - run: FILTER=test-select MYSQL_PORT=3306 bun run test \ No newline at end of file + run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun run test \ No newline at end of file diff --git a/test/common.js b/test/common.js index 6ba5ff332e..c2e08d85b3 100644 --- a/test/common.js +++ b/test/common.js @@ -12,7 +12,7 @@ const config = { port: process.env.MYSQL_PORT || 3306 }; -if (process.env.MYSQL_USE_TLS) { +if (process.env.MYSQL_USE_TLS === '1') { config.ssl = { rejectUnauthorized: false, ca: fs.readFileSync( @@ -84,6 +84,7 @@ exports.createConnection = function(args) { typeCast: args && args.typeCast, namedPlaceholders: args && args.namedPlaceholders, connectTimeout: args && args.connectTimeout, + ssl: (args && args.ssl) || config.ssl, }; const conn = driver.createConnection(params); diff --git a/test/integration/connection/test-select-ssl.js b/test/integration/connection/test-select-ssl.js new file mode 100644 index 0000000000..cdb9feb99d --- /dev/null +++ b/test/integration/connection/test-select-ssl.js @@ -0,0 +1,16 @@ +'use strict'; + +const assert = require('assert'); +const tls = require('tls'); +const common = require('../../common'); +const connection = common.createConnection(); + +connection.query(`SHOW STATUS LIKE 'Ssl_cipher'`, (err, rows, fields) => { + assert.ifError(err); + if (process.env.MYSQL_USE_TLS === '1') { + assert(rows[0].Value.startsWith('TLS_AES_')); + } else { + assert.deepEqual(rows, [{ Variable_name: 'Ssl_cipher', Value: '' }]); + } + connection.end(); +}); \ No newline at end of file From 0bc180c96fc461b2524ca81d6d68806490203e71 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 14:32:35 +1000 Subject: [PATCH 06/27] lint --- test/integration/connection/test-select-ssl.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/connection/test-select-ssl.js b/test/integration/connection/test-select-ssl.js index cdb9feb99d..a67e1bf1b4 100644 --- a/test/integration/connection/test-select-ssl.js +++ b/test/integration/connection/test-select-ssl.js @@ -1,7 +1,6 @@ 'use strict'; const assert = require('assert'); -const tls = require('tls'); const common = require('../../common'); const connection = common.createConnection(); From 7d327a9cb293e9d11d1d940eb733268f31030af9 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 14:34:07 +1000 Subject: [PATCH 07/27] bun: only run 2 basic tests for now --- .github/workflows/ci-bun.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index 7e467f3c4c..a5d499c5c1 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -57,6 +57,6 @@ jobs: - name: Wait mysql server is ready run: node tools/wait-up.js - - name: Run tests - # todo: run full test suite once test createServer is implemented using Bun.listen - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun run test \ No newline at end of file + # todo: run full test suite once test createServer is implemented using Bun.listen + - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-ssl.js + - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-select-1.js \ No newline at end of file From 47c2b5b695bec9a3bb1ae49a1f89eb9727909a58 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 14:41:29 +1000 Subject: [PATCH 08/27] lint --- test/integration/connection/test-select-ssl.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/connection/test-select-ssl.js b/test/integration/connection/test-select-ssl.js index a67e1bf1b4..d9a4059102 100644 --- a/test/integration/connection/test-select-ssl.js +++ b/test/integration/connection/test-select-ssl.js @@ -4,12 +4,12 @@ const assert = require('assert'); const common = require('../../common'); const connection = common.createConnection(); -connection.query(`SHOW STATUS LIKE 'Ssl_cipher'`, (err, rows, fields) => { +connection.query(`SHOW STATUS LIKE 'Ssl_cipher'`, (err, rows) => { assert.ifError(err); if (process.env.MYSQL_USE_TLS === '1') { assert(rows[0].Value.startsWith('TLS_AES_')); } else { - assert.deepEqual(rows, [{ Variable_name: 'Ssl_cipher', Value: '' }]); + assert.deepEqual(rows, [{ Variable_name: 'Ssl_cipher', Value: '' }]); } connection.end(); -}); \ No newline at end of file +}); From 84beaa58a888538d3fadad3a0b53b081953b45a1 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 16:31:15 +1000 Subject: [PATCH 09/27] don't enable ssl in test running against fake server --- test/common.js | 8 +++++--- test/integration/connection/test-disconnects.js | 3 ++- test/integration/connection/test-protocol-errors.js | 3 ++- test/integration/connection/test-quit.js | 3 ++- test/integration/connection/test-stream-errors.js | 6 +++++- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/test/common.js b/test/common.js index c2e08d85b3..094e1d6167 100644 --- a/test/common.js +++ b/test/common.js @@ -84,7 +84,7 @@ exports.createConnection = function(args) { typeCast: args && args.typeCast, namedPlaceholders: args && args.namedPlaceholders, connectTimeout: args && args.connectTimeout, - ssl: (args && args.ssl) || config.ssl, + ssl: (args && args.ssl) ?? config.ssl, }; const conn = driver.createConnection(params); @@ -165,10 +165,12 @@ exports.createServer = function(onListening, handler) { const server = require('../index.js').createServer(); server.on('connection', conn => { conn.on('error', () => { - // we are here when client drops connection + // server side of the connection + // ignore disconnects }); + // remove ssl bit from the flags let flags = 0xffffff; - flags = flags ^ ClientFlags.COMPRESS; + flags = flags ^ (ClientFlags.COMPRESS | ClientFlags.SSL); conn.serverHandshake({ protocolVersion: 10, diff --git a/test/integration/connection/test-disconnects.js b/test/integration/connection/test-disconnects.js index 660c21b2db..bee24bc842 100644 --- a/test/integration/connection/test-disconnects.js +++ b/test/integration/connection/test-disconnects.js @@ -23,7 +23,8 @@ const server = common.createServer( // different host provided via MYSQL_HOST that identifies a real MySQL // server instance. host: 'localhost', - port: server._port + port: server._port, + ssl: false }); connection.query('SELECT 123', (err, _rows, _fields) => { if (err) { diff --git a/test/integration/connection/test-protocol-errors.js b/test/integration/connection/test-protocol-errors.js index 4ef3517383..81a8c9c002 100644 --- a/test/integration/connection/test-protocol-errors.js +++ b/test/integration/connection/test-protocol-errors.js @@ -22,7 +22,8 @@ const server = common.createServer( // different host provided via MYSQL_HOST that identifies a real MySQL // server instance. host: 'localhost', - port: server._port + port: server._port, + ssl: false }); connection.query(query, (err, _rows, _fields) => { if (err) { diff --git a/test/integration/connection/test-quit.js b/test/integration/connection/test-quit.js index aa79e304e9..af8ff83de5 100644 --- a/test/integration/connection/test-quit.js +++ b/test/integration/connection/test-quit.js @@ -22,7 +22,8 @@ const server = common.createServer( // different host provided via MYSQL_HOST that identifies a real MySQL // server instance. host: 'localhost', - port: server._port + port: server._port, + ssl: false }); connection.query(queryCli, (err, _rows, _fields) => { diff --git a/test/integration/connection/test-stream-errors.js b/test/integration/connection/test-stream-errors.js index fd054b2c15..7082b4f986 100644 --- a/test/integration/connection/test-stream-errors.js +++ b/test/integration/connection/test-stream-errors.js @@ -25,9 +25,13 @@ const server = common.createServer( // different host provided via MYSQL_HOST that identifies a real MySQL // server instance. host: 'localhost', - port: server._port + port: server._port, + ssl: false }); clientConnection.query(query, err => { + if (err && err.code === 'HANDSHAKE_NO_SSL_SUPPORT') { + clientConnection.end(); + } receivedError1 = err; }); clientConnection.query('second query, should not be executed', () => { From 456a5225e146f9fc9e8cc1b1e117e09d1cdd495b Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 17:15:13 +1000 Subject: [PATCH 10/27] fix typo --- .github/workflows/ci-bun.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index a5d499c5c1..719e373986 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -59,4 +59,4 @@ jobs: # todo: run full test suite once test createServer is implemented using Bun.listen - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-ssl.js - - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-select-1.js \ No newline at end of file + - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-1.js \ No newline at end of file From 99b0b857d2c764f03e8be227d1f2c1eeaef21072 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 21:14:15 +1000 Subject: [PATCH 11/27] debug failures --- test/integration/regressions/test-#82.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/integration/regressions/test-#82.js b/test/integration/regressions/test-#82.js index 89121534fa..a8a571415c 100644 --- a/test/integration/regressions/test-#82.js +++ b/test/integration/regressions/test-#82.js @@ -1,5 +1,8 @@ 'use strict'; +// temporary disabling the test +return; + const common = require('../../common'); const connection = common.createConnection(); const assert = require('assert'); From 6c5879c52f1c77321e0abb039772e30fc19d6bce Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 7 Jul 2023 21:38:09 +1000 Subject: [PATCH 12/27] try bun canary --- .github/workflows/ci-bun.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index 719e373986..b49ab85059 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - bun-version: [0.6.13] + bun-version: [canary] mysql-version: ["mysql:5.7", "mysql:8.0.18", "mysql:8.0.22"] use-compression: [0] use-tls: [0,1] @@ -33,7 +33,7 @@ jobs: run: docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_DATABASE=${{ env.MYSQL_DATABASE }} -v $PWD/mysqldata:/var/lib/mysql/ -v $PWD/examples/custom-conf:/etc/mysql/conf.d -v $PWD/examples/ssl/certs:/certs -p ${{ env.MYSQL_PORT }}:3306 ${{ matrix.mysql-version }} - name: Set up Bun ${{ matrix.bun-version }} - uses: oven-sh/setup-bun@v0.1.8 + uses: oven-sh/setup-bun@v1 with: bun-version: ${{ matrix.bun-version }} @@ -58,5 +58,5 @@ jobs: run: node tools/wait-up.js # todo: run full test suite once test createServer is implemented using Bun.listen + - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-1.js - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-ssl.js - - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-1.js \ No newline at end of file From 583a317c5e283c7a3ba7c8b936c9192a823855ea Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 11:50:25 +1000 Subject: [PATCH 13/27] ci: add osx runner --- .github/workflows/ci-osx.yml | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/ci-osx.yml diff --git a/.github/workflows/ci-osx.yml b/.github/workflows/ci-osx.yml new file mode 100644 index 0000000000..749909c716 --- /dev/null +++ b/.github/workflows/ci-osx.yml @@ -0,0 +1,75 @@ +name: CI - OSX + +on: + pull_request: + push: + branches: [ main ] + + workflow_dispatch: + +env: + MYSQL_PORT: 3306 + MYSQL_USER: root + MYSQL_DATABASE: test + +jobs: + tests-osx: + runs-on: macos-13 + strategy: + fail-fast: false + matrix: + node-version: [18.x, 20.x] + mysql-version: ["mysql:8.0.22", "mysql:8.0.33"] + use-compression: [0, 1] + use-tls: [0] + mysql_connection_url_key: [""] + # TODO - add mariadb to the matrix. currently few tests are broken due to mariadb incompatibilities + include: + # 20.x + - node-version: "20.x" + mysql-version: "mysql:8.0.33" + use-compression: 1 + use-tls: 0 + use-builtin-test-runner: 1 + - node-version: "20.x" + mysql-version: "mysql:8.0.33" + use-compression: 0 + use-tls: 1 + use-builtin-test-runner: 1 + env: + MYSQL_CONNECTION_URL: ${{ secrets[matrix.mysql_connection_url_key] }} + + name: Node.js ${{ matrix.node-version }} - DB ${{ matrix.mysql-version }}${{ matrix.mysql_connection_url_key }} - SSL=${{matrix.use-tls}} Compression=${{matrix.use-compression}} + + steps: + - uses: actions/checkout@v3 + + - name: Set up MySQL + if: ${{ matrix.mysql-version }} + run: docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_DATABASE=${{ env.MYSQL_DATABASE }} -v $PWD/mysqldata:/var/lib/mysql/ -v $PWD/examples/custom-conf:/etc/mysql/conf.d -v $PWD/examples/ssl/certs:/certs -p ${{ env.MYSQL_PORT }}:3306 ${{ matrix.mysql-version }} + + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- + + - name: Install npm dependencies + run: npm ci + + - name: Wait mysql server is ready + if: ${{ matrix.mysql-version }} + run: node tools/wait-up.js + + - name: Run tests + run: FILTER=${{matrix.filter}} MYSQL_USE_TLS=${{ matrix.use-tls }} MYSQL_USE_COMPRESSION=${{ matrix.use-compression }} npm run coverage-test + + - name: Run tests with built-in node test runner + if: ${{ matrix.use-builtin-test-runner }} + run: FILTER=${{matrix.filter}} MYSQL_USE_TLS=${{ matrix.use-tls }} MYSQL_USE_COMPRESSION=${{ matrix.use-compression }} npm run test:builtin-node-runner \ No newline at end of file From 709091b8fd16aa0798a8d2c54dfd6400ec9bbb26 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 15:42:17 +1000 Subject: [PATCH 14/27] ci: install docker for osx --- .github/workflows/ci-osx.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci-osx.yml b/.github/workflows/ci-osx.yml index 749909c716..a3e1d25f26 100644 --- a/.github/workflows/ci-osx.yml +++ b/.github/workflows/ci-osx.yml @@ -44,6 +44,9 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Set up docker + uses: docker-practice/actions-setup-docker@v1 + - name: Set up MySQL if: ${{ matrix.mysql-version }} run: docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_DATABASE=${{ env.MYSQL_DATABASE }} -v $PWD/mysqldata:/var/lib/mysql/ -v $PWD/examples/custom-conf:/etc/mysql/conf.d -v $PWD/examples/ssl/certs:/certs -p ${{ env.MYSQL_PORT }}:3306 ${{ matrix.mysql-version }} From 9b2db1482171826e5a5efdac69c733aafa449c20 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 17:26:26 +1000 Subject: [PATCH 15/27] ci: install docker for osx --- .github/workflows/ci-osx.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-osx.yml b/.github/workflows/ci-osx.yml index a3e1d25f26..879a2541be 100644 --- a/.github/workflows/ci-osx.yml +++ b/.github/workflows/ci-osx.yml @@ -45,7 +45,13 @@ jobs: - uses: actions/checkout@v3 - name: Set up docker - uses: docker-practice/actions-setup-docker@v1 + run: | + brew install docker + brew install docker-compose + brew install docker-machine + docker-machine create --driver virtualbox default + docker-machine env default + eval $(docker-machine env default) - name: Set up MySQL if: ${{ matrix.mysql-version }} From f00b840f778ef8ba9cbf53563e410347ce740b4f Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 22:19:06 +1000 Subject: [PATCH 16/27] ci: install docker for osx --- .github/workflows/ci-osx.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-osx.yml b/.github/workflows/ci-osx.yml index 879a2541be..b163452513 100644 --- a/.github/workflows/ci-osx.yml +++ b/.github/workflows/ci-osx.yml @@ -44,15 +44,9 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up docker - run: | - brew install docker - brew install docker-compose - brew install docker-machine - docker-machine create --driver virtualbox default - docker-machine env default - eval $(docker-machine env default) - + - name: Setup Docker on macOS + uses: douglascamata/setup-docker-macos-action@v1-alpha + - name: Set up MySQL if: ${{ matrix.mysql-version }} run: docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_DATABASE=${{ env.MYSQL_DATABASE }} -v $PWD/mysqldata:/var/lib/mysql/ -v $PWD/examples/custom-conf:/etc/mysql/conf.d -v $PWD/examples/ssl/certs:/certs -p ${{ env.MYSQL_PORT }}:3306 ${{ matrix.mysql-version }} From 3036c51c30675e602707527142dbd0fee9cd4a90 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 22:34:59 +1000 Subject: [PATCH 17/27] ci: osx - don't mount config in docker --- .github/workflows/ci-osx.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-osx.yml b/.github/workflows/ci-osx.yml index b163452513..d409d735c0 100644 --- a/.github/workflows/ci-osx.yml +++ b/.github/workflows/ci-osx.yml @@ -49,7 +49,7 @@ jobs: - name: Set up MySQL if: ${{ matrix.mysql-version }} - run: docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_DATABASE=${{ env.MYSQL_DATABASE }} -v $PWD/mysqldata:/var/lib/mysql/ -v $PWD/examples/custom-conf:/etc/mysql/conf.d -v $PWD/examples/ssl/certs:/certs -p ${{ env.MYSQL_PORT }}:3306 ${{ matrix.mysql-version }} + run: docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -e MYSQL_DATABASE=${{ env.MYSQL_DATABASE }} -p ${{ env.MYSQL_PORT }}:3306 ${{ matrix.mysql-version }} - name: Set up Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 From fe27ed1e32d8d1e6137a05a392aabc2f66d290df Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 22:44:08 +1000 Subject: [PATCH 18/27] handle ECONNREFUSED in waitDatabaseReady helper --- test/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common.js b/test/common.js index 094e1d6167..9e9d057e9e 100644 --- a/test/common.js +++ b/test/common.js @@ -32,7 +32,7 @@ exports.waitDatabaseReady = function(callback) { const tryConnect = function() { const conn = exports.createConnection({ database: 'mysql', password: process.env.MYSQL_PASSWORD }); conn.once('error', err => { - if (err.code !== 'PROTOCOL_CONNECTION_LOST' && err.code !== 'ETIMEDOUT') { + if (err.code !== 'PROTOCOL_CONNECTION_LOST' && err.code !== 'ETIMEDOUT' && err.code !== 'ECONNREFUSED') { console.log('Unexpected error waiting for connection', err); process.exit(-1); } From 585c3f1857c42f1064dec3bd4603ca16a249d98e Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 22:58:04 +1000 Subject: [PATCH 19/27] comment out instead of early return --- test/integration/regressions/test-#82.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/integration/regressions/test-#82.js b/test/integration/regressions/test-#82.js index a8a571415c..736b15e0d0 100644 --- a/test/integration/regressions/test-#82.js +++ b/test/integration/regressions/test-#82.js @@ -1,6 +1,7 @@ 'use strict'; // temporary disabling the test +/* return; const common = require('../../common'); @@ -63,3 +64,4 @@ process.on('exit', () => { assert.equal(results[2].name2, 'BB'); assert.equal(results[3].name2, 'AA'); }); +*/ \ No newline at end of file From a73e90d08e89921cfb7604f9cda1ec92ce306aa3 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 23:04:01 +1000 Subject: [PATCH 20/27] explicitly install lima --- .github/workflows/ci-osx.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci-osx.yml b/.github/workflows/ci-osx.yml index d409d735c0..995d44583c 100644 --- a/.github/workflows/ci-osx.yml +++ b/.github/workflows/ci-osx.yml @@ -44,6 +44,9 @@ jobs: steps: - uses: actions/checkout@v3 + - name: install lima + run: brew install lima + - name: Setup Docker on macOS uses: douglascamata/setup-docker-macos-action@v1-alpha From cbb2f9456cab7f950aa5c8a726a8900549494953 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 23:27:04 +1000 Subject: [PATCH 21/27] use connection.end() instead of destroy --- test/integration/connection/test-then-on-query.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/connection/test-then-on-query.js b/test/integration/connection/test-then-on-query.js index 2f28eb8238..61dc7a3d90 100644 --- a/test/integration/connection/test-then-on-query.js +++ b/test/integration/connection/test-then-on-query.js @@ -13,7 +13,7 @@ try { error = false; } q.on('end', () => { - connection.destroy(); + connection.end(); }); process.on('exit', () => { From c4e45b8b5ba79345143a8cbcc4efd243061643ce Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sat, 8 Jul 2023 23:38:50 +1000 Subject: [PATCH 22/27] debug Ssl_cipher assertion --- test/integration/connection/test-select-ssl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/connection/test-select-ssl.js b/test/integration/connection/test-select-ssl.js index d9a4059102..b99549fb99 100644 --- a/test/integration/connection/test-select-ssl.js +++ b/test/integration/connection/test-select-ssl.js @@ -7,7 +7,7 @@ const connection = common.createConnection(); connection.query(`SHOW STATUS LIKE 'Ssl_cipher'`, (err, rows) => { assert.ifError(err); if (process.env.MYSQL_USE_TLS === '1') { - assert(rows[0].Value.startsWith('TLS_AES_')); + assert.equal(rows[0].Value.slice(0, 8), 'TLS_AES_'); } else { assert.deepEqual(rows, [{ Variable_name: 'Ssl_cipher', Value: '' }]); } From 7eb32af91fdf6c3f141361242236f44d1f46be62 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sun, 9 Jul 2023 00:45:41 +1000 Subject: [PATCH 23/27] more flexible Ssl_cipher assertion --- test/integration/connection/test-select-ssl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/connection/test-select-ssl.js b/test/integration/connection/test-select-ssl.js index b99549fb99..880b1f9be6 100644 --- a/test/integration/connection/test-select-ssl.js +++ b/test/integration/connection/test-select-ssl.js @@ -7,7 +7,7 @@ const connection = common.createConnection(); connection.query(`SHOW STATUS LIKE 'Ssl_cipher'`, (err, rows) => { assert.ifError(err); if (process.env.MYSQL_USE_TLS === '1') { - assert.equal(rows[0].Value.slice(0, 8), 'TLS_AES_'); + assert.equal(rows[0].Value.length > 0, true); } else { assert.deepEqual(rows, [{ Variable_name: 'Ssl_cipher', Value: '' }]); } From 1a594f22085833b82ebab00d84b15c8b5354858b Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sun, 9 Jul 2023 13:10:00 +1000 Subject: [PATCH 24/27] initialize packet header befor writing --- test/builtin-runner/regressions/2052.test.mjs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/builtin-runner/regressions/2052.test.mjs b/test/builtin-runner/regressions/2052.test.mjs index 2bc5a83c83..0e4944a990 100644 --- a/test/builtin-runner/regressions/2052.test.mjs +++ b/test/builtin-runner/regressions/2052.test.mjs @@ -10,6 +10,7 @@ describe( () => { it('should report 0 actual parameters when 1 placeholder is used in ORDER BY ?', (t, done) => { const connection = { + sequenceId: 1, constructor: { statementKey: () => 0, }, @@ -23,9 +24,10 @@ describe( }, writePacket: (packet) => { // client -> server COM_PREPARE + packet.writeHeader(1); assert.equal( packet.buffer.toString('hex'), - '000000001673656c656374202a2066726f6d207573657273206f72646572206279203f' + '1f0000011673656c656374202a2066726f6d207573657273206f72646572206279203f' ); }, }; @@ -68,7 +70,7 @@ describe( } ); -describe('E2E Prepare result with number of parameters incorrectly reported by the server', { timeout: 1000 }, () => { +describe.skip('E2E Prepare result with number of parameters incorrectly reported by the server', { timeout: 1000 }, () => { let connection; function isNewerThan8_0_22() { From f0650554e943363c46f39c548a12faab8cb9bf92 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Sun, 9 Jul 2023 13:59:09 +1000 Subject: [PATCH 25/27] cleanup --- lib/connection.js | 20 +------------------ test/builtin-runner/regressions/2052.test.mjs | 4 +++- test/integration/regressions/test-#82.js | 9 ++------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index e5cb24f043..d6ad7a4f9b 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -355,7 +355,7 @@ class Connection extends EventEmitter { }); const rejectUnauthorized = this.config.ssl.rejectUnauthorized; const verifyIdentity = this.config.ssl.verifyIdentity; - const servername = this.config.host + const servername = this.config.host; let secureEstablished = false; this.stream.removeAllListeners('data'); @@ -394,24 +394,6 @@ class Connection extends EventEmitter { this.write = buffer => secureSocket.write(buffer); } - /* - pipe() { - if (this.stream instanceof Net.Stream) { - this.stream.ondata = (data, start, end) => { - this.packetParser.execute(data, start, end); - }; - } else { - this.stream.on('data', data => { - this.packetParser.execute( - data.parent, - data.offset, - data.offset + data.length - ); - }); - } - } - */ - protocolError(message, code) { // Starting with MySQL 8.0.24, if the client closes the connection // unexpectedly, the server will send a last ERR Packet, which we can diff --git a/test/builtin-runner/regressions/2052.test.mjs b/test/builtin-runner/regressions/2052.test.mjs index 0e4944a990..d12865cf6c 100644 --- a/test/builtin-runner/regressions/2052.test.mjs +++ b/test/builtin-runner/regressions/2052.test.mjs @@ -70,7 +70,9 @@ describe( } ); -describe.skip('E2E Prepare result with number of parameters incorrectly reported by the server', { timeout: 1000 }, () => { +describe('E2E Prepare result with number of parameters incorrectly reported by the server', + { timeout: 1000 }, + () => { let connection; function isNewerThan8_0_22() { diff --git a/test/integration/regressions/test-#82.js b/test/integration/regressions/test-#82.js index 736b15e0d0..e7b9e29a06 100644 --- a/test/integration/regressions/test-#82.js +++ b/test/integration/regressions/test-#82.js @@ -1,9 +1,5 @@ 'use strict'; -// temporary disabling the test -/* -return; - const common = require('../../common'); const connection = common.createConnection(); const assert = require('assert'); @@ -49,7 +45,7 @@ prepareTestSet(err => { (err, rows) => { assert.ifError(err); results = rows; - connection.close(); + connection.end(); } ); }); @@ -63,5 +59,4 @@ process.on('exit', () => { assert.equal(results[1].name2, 'CC'); assert.equal(results[2].name2, 'BB'); assert.equal(results[3].name2, 'AA'); -}); -*/ \ No newline at end of file +}); \ No newline at end of file From 4c64210756bf257d237cab5335c6b20454e53b1b Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Mon, 10 Jul 2023 12:18:33 +1000 Subject: [PATCH 26/27] add compression to bun matrix --- .github/workflows/ci-bun.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index b49ab85059..574d5e0b62 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -20,9 +20,9 @@ jobs: strategy: fail-fast: false matrix: - bun-version: [canary] + bun-version: [0.6.13, canary] mysql-version: ["mysql:5.7", "mysql:8.0.18", "mysql:8.0.22"] - use-compression: [0] + use-compression: [0, 1] use-tls: [0,1] name: Bun ${{ matrix.bun-version }} - DB ${{ matrix.mysql-version }} - SSL=${{matrix.use-tls}} Compression=${{matrix.use-compression}} @@ -58,5 +58,13 @@ jobs: run: node tools/wait-up.js # todo: run full test suite once test createServer is implemented using Bun.listen - - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-1.js - - run: MYSQL_USE_TLS=${{ matrix.use-tls }} FILTER=test-select MYSQL_PORT=3306 bun test/integration/connection/test-select-ssl.js + - name: run tests + env: + MYSQL_USER: ${{ env.MYSQL_USER }} + MYSQL_DATABASE: ${{ env.MYSQL_DATABASE }} + MYSQL_PORT: ${{ env.MYSQL_PORT }} + MYSQL_USE_COMPRESSION: ${{ matrix.use-compression }} + MYSQL_USE_TLS: ${{ matrix.use-tls }} + run: | + bun test/integration/connection/test-select-1.js + bun test/integration/connection/test-select-ssl.js \ No newline at end of file From 75ae09035e7e4902ac48d11c851466a1b2bee4c7 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Mon, 10 Jul 2023 12:23:49 +1000 Subject: [PATCH 27/27] only use bun v0.6.13 for non-ssl tests --- .github/workflows/ci-bun.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml index 574d5e0b62..b1d3c8cf34 100644 --- a/.github/workflows/ci-bun.yml +++ b/.github/workflows/ci-bun.yml @@ -20,10 +20,19 @@ jobs: strategy: fail-fast: false matrix: - bun-version: [0.6.13, canary] + bun-version: [canary] mysql-version: ["mysql:5.7", "mysql:8.0.18", "mysql:8.0.22"] use-compression: [0, 1] use-tls: [0,1] + include: + - bun-version: "0.6.13" + use-compression: 1 + use-tls: 0 + mysql-version: "mysql:8.0.18" + - bun-version: "0.6.13" + use-compression: 1 + use-tls: 0 + mysql-version: "mysql:8.0.22" name: Bun ${{ matrix.bun-version }} - DB ${{ matrix.mysql-version }} - SSL=${{matrix.use-tls}} Compression=${{matrix.use-compression}}