From 830d454c3c07abab3e0e1f06f74a8e00d06b668e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Fri, 22 May 2015 14:16:07 +0100 Subject: [PATCH 1/6] test: running tls-server-verify clients in parallel OpenSSL s_client introduces some delay on Windows. With all clients running sequentially, this delay is big enough to break CI. This fix runs the clients in parallel (unless the test includes renegotiation), reducing the total run time. (cherry picked from commit 12d4ea3c8ae7f8011de9ca9f50bdc08ee8cfb8bf) --- test/parallel/test-tls-server-verify.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index f30134f04ac0a5..2db47d32d835fb 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -307,7 +307,21 @@ function runTest(testIndex) { if (tcase.debug) { console.error('TLS server running on port ' + common.PORT); } else { - runNextClient(0); + if (tcase.renegotiate) { + runNextClient(0); + } else { + var clientsCompleted = 0; + for (var i = 0; i < tcase.clients.length; i++) { + runClient(tcase.clients[i], function() { + clientsCompleted++; + if (clientsCompleted === tcase.clients.length) { + server.close(); + successfulTests++; + runTest(testIndex + 1); + } + }); + } + } } }); } From 1bcb5f0302204b42d6a3df54bf64ceb56056ff33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Fri, 22 May 2015 14:28:11 +0100 Subject: [PATCH 2/6] test: run tls-server-verify servers in parallel Different servers must use different ports. Since we can count only on common.PORT and common.PORT+1, run only 2 servers in parallel. (cherry picked from commit efb0075ee0e1f4123974fe5b74ded8727bad4a9e) --- test/parallel/test-tls-server-verify.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index 2db47d32d835fb..f208ca519ca240 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -125,14 +125,14 @@ var serverKey = loadPEM('agent2-key'); var serverCert = loadPEM('agent2-cert'); -function runClient(options, cb) { +function runClient(port, options, cb) { // Client can connect in three ways: // - Self-signed cert // - Certificate, but not signed by CA. // - Certificate signed by CA. - var args = ['s_client', '-connect', '127.0.0.1:' + common.PORT]; + var args = ['s_client', '-connect', '127.0.0.1:' + port]; console.log(' connecting with', options.name); @@ -230,7 +230,7 @@ function runClient(options, cb) { // Run the tests var successfulTests = 0; -function runTest(testIndex) { +function runTest(port, testIndex) { var tcase = testCases[testIndex]; if (!tcase) return; @@ -293,31 +293,31 @@ function runTest(testIndex) { function runNextClient(clientIndex) { var options = tcase.clients[clientIndex]; if (options) { - runClient(options, function() { + runClient(port, options, function() { runNextClient(clientIndex + 1); }); } else { server.close(); successfulTests++; - runTest(testIndex + 1); + runTest(port, nextTest++); } } - server.listen(common.PORT, function() { + server.listen(port, function() { if (tcase.debug) { - console.error('TLS server running on port ' + common.PORT); + console.error('TLS server running on port ' + port); } else { if (tcase.renegotiate) { runNextClient(0); } else { var clientsCompleted = 0; for (var i = 0; i < tcase.clients.length; i++) { - runClient(tcase.clients[i], function() { + runClient(port, tcase.clients[i], function() { clientsCompleted++; if (clientsCompleted === tcase.clients.length) { server.close(); successfulTests++; - runTest(testIndex + 1); + runTest(port, nextTest++); } }); } @@ -327,7 +327,9 @@ function runTest(testIndex) { } -runTest(0); +var nextTest = 0; +runTest(common.PORT, nextTest++); +runTest(common.PORT + 1, nextTest++); process.on('exit', function() { From f49019f1f415619dd83738713d46f60026448a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Fri, 22 May 2015 14:43:16 +0100 Subject: [PATCH 3/6] test: improve console output of tls-server-verify When running in parallel, it is not easy to identify what server and client failed when the test fails. This adds identifiers to all lines of console output. (cherry picked from commit 29c651522df2f47c4360660264eb857fb6232b23) --- test/parallel/test-tls-server-verify.js | 35 ++++++++++++++----------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index f208ca519ca240..556dc2376a2ac5 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -125,7 +125,7 @@ var serverKey = loadPEM('agent2-key'); var serverCert = loadPEM('agent2-cert'); -function runClient(port, options, cb) { +function runClient(prefix, port, options, cb) { // Client can connect in three ways: // - Self-signed cert @@ -135,7 +135,7 @@ function runClient(port, options, cb) { var args = ['s_client', '-connect', '127.0.0.1:' + port]; - console.log(' connecting with', options.name); + console.log(prefix + ' connecting with', options.name); switch (options.name) { case 'agent1': @@ -176,7 +176,7 @@ function runClient(port, options, cb) { break; default: - throw new Error('Unknown agent name'); + throw new Error(prefix + 'Unknown agent name'); } // To test use: openssl s_client -connect localhost:8000 @@ -193,7 +193,7 @@ function runClient(port, options, cb) { out += d; if (!goodbye && /_unauthed/g.test(out)) { - console.error(' * unauthed'); + console.error(prefix + ' * unauthed'); goodbye = true; client.stdin.end('goodbye\n'); authed = false; @@ -201,7 +201,7 @@ function runClient(port, options, cb) { } if (!goodbye && /_authed/g.test(out)) { - console.error(' * authed'); + console.error(prefix + ' * authed'); goodbye = true; client.stdin.end('goodbye\n'); authed = true; @@ -212,15 +212,17 @@ function runClient(port, options, cb) { //client.stdout.pipe(process.stdout); client.on('exit', function(code) { - //assert.equal(0, code, options.name + + //assert.equal(0, code, prefix + options.name + // ": s_client exited with error code " + code); if (options.shouldReject) { - assert.equal(true, rejected, options.name + + assert.equal(true, rejected, prefix + options.name + ' NOT rejected, but should have been'); } else { - assert.equal(false, rejected, options.name + + assert.equal(false, rejected, prefix + options.name + ' rejected, but should NOT have been'); - assert.equal(options.shouldAuth, authed); + assert.equal(options.shouldAuth, authed, prefix + + options.name + ' authed is ' + authed + + ' but should have been ' + options.shouldAuth); } cb(); @@ -231,10 +233,11 @@ function runClient(port, options, cb) { // Run the tests var successfulTests = 0; function runTest(port, testIndex) { + var prefix = testIndex + ' '; var tcase = testCases[testIndex]; if (!tcase) return; - console.error("Running '%s'", tcase.title); + console.error(prefix + "Running '%s'", tcase.title); var cas = tcase.CAs.map(loadPEM); @@ -265,7 +268,7 @@ function runTest(port, testIndex) { if (tcase.renegotiate && !renegotiated) { renegotiated = true; setTimeout(function() { - console.error('- connected, renegotiating'); + console.error(prefix + '- connected, renegotiating'); c.write('\n_renegotiating\n'); return c.renegotiate({ requestCert: true, @@ -281,11 +284,11 @@ function runTest(port, testIndex) { connections++; if (c.authorized) { - console.error('- authed connection: ' + + console.error(prefix + '- authed connection: ' + c.getPeerCertificate().subject.CN); c.write('\n_authed\n'); } else { - console.error('- unauthed connection: %s', c.authorizationError); + console.error(prefix + '- unauthed connection: %s', c.authorizationError); c.write('\n_unauthed\n'); } }); @@ -293,7 +296,7 @@ function runTest(port, testIndex) { function runNextClient(clientIndex) { var options = tcase.clients[clientIndex]; if (options) { - runClient(port, options, function() { + runClient(prefix + clientIndex + ' ', port, options, function() { runNextClient(clientIndex + 1); }); } else { @@ -305,14 +308,14 @@ function runTest(port, testIndex) { server.listen(port, function() { if (tcase.debug) { - console.error('TLS server running on port ' + port); + console.error(prefix + 'TLS server running on port ' + port); } else { if (tcase.renegotiate) { runNextClient(0); } else { var clientsCompleted = 0; for (var i = 0; i < tcase.clients.length; i++) { - runClient(port, tcase.clients[i], function() { + runClient(prefix + i + ' ', port, tcase.clients[i], function() { clientsCompleted++; if (clientsCompleted === tcase.clients.length) { server.close(); From 03680032fdc7b6e4409e918d5cdc07cabcc0d45a Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Wed, 27 May 2015 10:16:51 +0900 Subject: [PATCH 4/6] test: kill child in tls-server-verify for speed up For better performance of the test, the parent kills child processes so as not to wait them to be ended. (cherry picked from commit 833b23636045f7afc929196139021630a390391a) --- test/parallel/test-tls-server-verify.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index 556dc2376a2ac5..6ee8ac433ecd89 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -195,7 +195,7 @@ function runClient(prefix, port, options, cb) { if (!goodbye && /_unauthed/g.test(out)) { console.error(prefix + ' * unauthed'); goodbye = true; - client.stdin.end('goodbye\n'); + client.kill(); authed = false; rejected = false; } @@ -203,7 +203,7 @@ function runClient(prefix, port, options, cb) { if (!goodbye && /_authed/g.test(out)) { console.error(prefix + ' * authed'); goodbye = true; - client.stdin.end('goodbye\n'); + client.kill(); authed = true; rejected = false; } @@ -265,6 +265,12 @@ function runTest(port, testIndex) { var renegotiated = false; var server = tls.Server(serverOptions, function handleConnection(c) { + c.on('error', function(e) { + // child.kill() leads ECONNRESET errro in the TLS connection of + // openssl s_client via spawn(). A Test result is already + // checked by the data of client.stdout before child.kill() so + // these tls errors can be ignored. + }); if (tcase.renegotiate && !renegotiated) { renegotiated = true; setTimeout(function() { From 2107be04ceea35803c92aa003b30992066413714 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Wed, 27 May 2015 10:33:38 +0900 Subject: [PATCH 5/6] deps: add -no_rand_screen to openssl s_client In openssl s_client on Windows, RAND_screen() is invoked to initialize random state but it takes several seconds in each connection. This added -no_rand_screen to openssl s_client on Windows to skip RAND_screen() and gets a better performance in the unit test of test-tls-server-verify. Do not enable this except to use in the unit test. (cherry picked from commit 9f0f7c38e6df975dd39735d0e9ef968076369c74) --- deps/openssl/openssl/apps/app_rand.c | 14 ++++++++++---- deps/openssl/openssl/apps/s_client.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/deps/openssl/openssl/apps/app_rand.c b/deps/openssl/openssl/apps/app_rand.c index 595fc7821c85e6..b6fe294a682711 100644 --- a/deps/openssl/openssl/apps/app_rand.c +++ b/deps/openssl/openssl/apps/app_rand.c @@ -124,10 +124,16 @@ int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn) char buffer[200]; #ifdef OPENSSL_SYS_WINDOWS - BIO_printf(bio_e, "Loading 'screen' into random state -"); - BIO_flush(bio_e); - RAND_screen(); - BIO_printf(bio_e, " done\n"); + /* + * allocate 2 to dont_warn not to use RAND_screen() via + * -no_rand_screen option in s_client + */ + if (dont_warn != 2) { + BIO_printf(bio_e, "Loading 'screen' into random state -"); + BIO_flush(bio_e); + RAND_screen(); + BIO_printf(bio_e, " done\n"); + } #endif if (file == NULL) diff --git a/deps/openssl/openssl/apps/s_client.c b/deps/openssl/openssl/apps/s_client.c index 7112b246d1d0de..d5297d3070de92 100644 --- a/deps/openssl/openssl/apps/s_client.c +++ b/deps/openssl/openssl/apps/s_client.c @@ -236,6 +236,7 @@ static BIO *bio_c_msg = NULL; static int c_quiet = 0; static int c_ign_eof = 0; static int c_brief = 0; +static int c_no_rand_screen = 0; #ifndef OPENSSL_NO_PSK /* Default PSK identity and key */ @@ -446,6 +447,10 @@ static void sc_usage(void) " -keymatexport label - Export keying material using label\n"); BIO_printf(bio_err, " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); +#ifdef OPENSSL_SYS_WINDOWS + BIO_printf(bio_err, + " -no_rand_screen - Do not use RAND_screen() to initialize random state\n"); +#endif } #ifndef OPENSSL_NO_TLSEXT @@ -1125,6 +1130,10 @@ int MAIN(int argc, char **argv) keymatexportlen = atoi(*(++argv)); if (keymatexportlen == 0) goto bad; +#ifdef OPENSSL_SYS_WINDOWS + } else if (strcmp(*argv, "-no_rand_screen") == 0) { + c_no_rand_screen = 1; +#endif } else { BIO_printf(bio_err, "unknown option %s\n", *argv); badop = 1; @@ -1230,7 +1239,7 @@ int MAIN(int argc, char **argv) if (!load_excert(&exc, bio_err)) goto end; - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL + if (!app_RAND_load_file(NULL, bio_err, ++c_no_rand_screen) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); From e809f012e5e00dbbd9a9756abb4bc2042f066909 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Wed, 27 May 2015 10:41:43 +0900 Subject: [PATCH 6/6] test: add -no_rand_screen for tls-server-verify This improves the performance of openssl s_client on Windows and gains several seconds to finish test-tls-server-verify. (cherry picked from commit 2ff517e0e410ea33ba5a3d289a82fc315d120e8e) --- test/parallel/test-tls-server-verify.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index 6ee8ac433ecd89..387ede8abc3554 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -134,6 +134,9 @@ function runClient(prefix, port, options, cb) { var args = ['s_client', '-connect', '127.0.0.1:' + port]; + // for the performance issue in s_client on Windows + if (process.platform === 'win32') + args.push('-no_rand_screen'); console.log(prefix + ' connecting with', options.name);