From a52feab157836eba21e8a06fb24eb6caeb094d3d Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 28 Aug 2015 19:56:22 -0700 Subject: [PATCH] test: refactor to eliminate flaky test This retains the key elements of test-child-process-fork-getconnections (forks a child process, sends a bunch of sockets, uses getConnections() to enumerate them) but contains some code to work around an apparent intermittent bug that occurs on OS X where a socket seems to close itself unexpectedly. https://github.com/nodejs/node/issues/2610 was opened for the bug that was causing the problem in the first place. PR-URL: https://github.com/nodejs/node/pull/2609 Fixes: https://github.com/nodejs/node/issues/1100 --- test/sequential/sequential.status | 1 - .../test-child-process-fork-getconnections.js | 59 ++++++++++--------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status index f61d98b63a0035..e7f0ca2b323992 100644 --- a/test/sequential/sequential.status +++ b/test/sequential/sequential.status @@ -5,7 +5,6 @@ prefix sequential # sample-test : PASS,FLAKY [true] # This section applies to all platforms -test-child-process-fork-getconnections : PASS,FLAKY test-repl-persistent-history : PASS,FLAKY [$system==win32] diff --git a/test/sequential/test-child-process-fork-getconnections.js b/test/sequential/test-child-process-fork-getconnections.js index a587713b6132f2..934df28d7988b7 100644 --- a/test/sequential/test-child-process-fork-getconnections.js +++ b/test/sequential/test-child-process-fork-getconnections.js @@ -1,48 +1,52 @@ 'use strict'; -var assert = require('assert'); -var common = require('../common'); -var fork = require('child_process').fork; -var net = require('net'); -var count = 12; +const assert = require('assert'); +const common = require('../common'); +const fork = require('child_process').fork; +const net = require('net'); +const count = 12; if (process.argv[2] === 'child') { - var sockets = []; - var id = process.argv[3]; + let sockets = []; process.on('message', function(m, socket) { + function sendClosed(id) { + process.send({ id: id, status: 'closed'}); + }; + if (m.cmd === 'new') { assert(socket); assert(socket instanceof net.Socket, 'should be a net.Socket'); sockets.push(socket); - socket.on('end', function() { - if (!this.closingOnPurpose) - throw new Error('[c] closing by accident!'); - }); } if (m.cmd === 'close') { assert.equal(socket, undefined); - sockets[m.id].once('close', function() { - process.send({ id: m.id, status: 'closed' }); - }); - sockets[m.id].destroy(); + if (sockets[m.id].destroyed) { + // Workaround for https://github.com/nodejs/node/issues/2610 + sendClosed(m.id); + // End of workaround. When bug is fixed, this code can be used instead: + // throw new Error('socket destroyed unexpectedly!'); + } else { + sockets[m.id].once('close', sendClosed.bind(null, m.id)); + sockets[m.id].destroy(); + } } }); } else { - var child = fork(process.argv[1], ['child']); + const child = fork(process.argv[1], ['child']); child.on('exit', function(code, signal) { if (!childKilled) throw new Error('child died unexpectedly!'); }); - var server = net.createServer(); - var sockets = []; - var sent = 0; + const server = net.createServer(); + let sockets = []; + let sent = 0; server.on('connection', function(socket) { - child.send({ cmd: 'new' }, socket, { track: false }); + child.send({ cmd: 'new' }, socket); sockets.push(socket); if (sockets.length === count) { @@ -50,21 +54,18 @@ if (process.argv[2] === 'child') { } }); - var disconnected = 0; - var clients = []; + let disconnected = 0; server.on('listening', function() { - var j = count, client; + let j = count, client; while (j--) { client = net.connect(common.PORT, '127.0.0.1'); - client.id = j; client.on('close', function() { disconnected += 1; }); - clients.push(client); } }); - var childKilled = false; + let childKilled = false; function closeSockets(i) { if (i === count) { childKilled = true; @@ -73,17 +74,17 @@ if (process.argv[2] === 'child') { return; } - sent++; - child.send({ id: i, cmd: 'close' }); child.once('message', function(m) { assert(m.status === 'closed'); server.getConnections(function(err, num) { closeSockets(i + 1); }); }); + sent++; + child.send({ id: i, cmd: 'close' }); }; - var closeEmitted = false; + let closeEmitted = false; server.on('close', function() { closeEmitted = true; });