From 1316b7652a50da7e996897edfab9a1d3c365d3b5 Mon Sep 17 00:00:00 2001
From: Sam Roberts <vieuxtech@gmail.com>
Date: Wed, 9 Jan 2019 14:03:31 -0800
Subject: [PATCH] test: do not race connection and rejection

Existing code assumed that the server completed the handshake before the
client rejected the certificate, and destroyed the socket. This
assumption is fragile, remove it, and instead check explicitly that data
can or cannot be exchanged via TLS, whichever is expected.

PR-URL: https://github.com/nodejs/node/pull/25508
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 test/parallel/test-tls-client-reject.js | 38 +++++++++++++++----------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/test/parallel/test-tls-client-reject.js b/test/parallel/test-tls-client-reject.js
index 955d97da6fb6fc..9eff6cb9cead01 100644
--- a/test/parallel/test-tls-client-reject.js
+++ b/test/parallel/test-tls-client-reject.js
@@ -33,49 +33,57 @@ const options = {
   cert: fixtures.readSync('test_cert.pem')
 };
 
-const server = tls.createServer(options, common.mustCall(function(socket) {
-  socket.on('data', function(data) {
-    console.error(data.toString());
-    assert.strictEqual(data.toString(), 'ok');
-  });
-}, 3)).listen(0, function() {
+const server = tls.createServer(options, function(socket) {
+  socket.pipe(socket);
+  socket.on('end', () => socket.end());
+}).listen(0, common.mustCall(function() {
   unauthorized();
-});
+}));
 
 function unauthorized() {
+  console.log('connect unauthorized');
   const socket = tls.connect({
     port: server.address().port,
     servername: 'localhost',
     rejectUnauthorized: false
   }, common.mustCall(function() {
+    console.log('... unauthorized');
     assert(!socket.authorized);
-    socket.end();
-    rejectUnauthorized();
+    socket.on('data', common.mustCall((data) => {
+      assert.strictEqual(data.toString(), 'ok');
+    }));
+    socket.on('end', () => rejectUnauthorized());
   }));
   socket.on('error', common.mustNotCall());
-  socket.write('ok');
+  socket.end('ok');
 }
 
 function rejectUnauthorized() {
+  console.log('reject unauthorized');
   const socket = tls.connect(server.address().port, {
     servername: 'localhost'
   }, common.mustNotCall());
+  socket.on('data', common.mustNotCall());
   socket.on('error', common.mustCall(function(err) {
-    console.error(err);
+    console.log('... rejected:', err);
     authorized();
   }));
-  socket.write('ng');
+  socket.end('ng');
 }
 
 function authorized() {
+  console.log('connect authorized');
   const socket = tls.connect(server.address().port, {
     ca: [fixtures.readSync('test_cert.pem')],
     servername: 'localhost'
   }, common.mustCall(function() {
+    console.log('... authorized');
     assert(socket.authorized);
-    socket.end();
-    server.close();
+    socket.on('data', common.mustCall((data) => {
+      assert.strictEqual(data.toString(), 'ok');
+    }));
+    socket.on('end', () => server.close());
   }));
   socket.on('error', common.mustNotCall());
-  socket.write('ok');
+  socket.end('ok');
 }