0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
nodejs/test/parallel/test-http-destroyed-socket-write2.js
Michael Dawson 5abfa930b8 test: make destroyed-socket-write2.js more robust
test/simple/test-http-destroyed-socket-write2.js validates
that you get an appropriate error when trying to write to
a request when the response on the other side has been destroyed.

The test uses http.request to get a request and then keeps writing
to it until either it hits 128 writes or gets the expected error.
Since the writes are asynchronous we see that the writes just end
up adding events to the event loop, which then later get processed
once the connection supporting the request is fully ready.

The test is timing dependent and if takes too long for the connection
to be made the limit of 128 writes is exceeded and the test fails.
The fact that the test allows a number of writes is probably to allow
some delay for the connection to be ready for writing.

On AIX, in the default configuration using the loopback interface
is slower and the test fails because the delay is such that many
more writes can be queued up before the connection takes place.
If we use the host ip instead of defaulting to the loopback then
the test passes.

The test needs to be made more robust to delays. Since each write
simply enqueues an additional write to the event queue there is
probably no point in doing the second write until the first has
completed. This patch schedules the next write when the first one
completes and allows the test to pass even if it takes longer for
the connection to be ready for writing

PR-URL: https://github.com/joyent/node/pull/9270
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Timothy J Fontaine <tjfontaine@gmail.com>
2015-03-03 10:03:42 -05:00

95 lines
2.1 KiB
JavaScript

var common = require('../common');
var assert = require('assert');
// Verify that ECONNRESET is raised when writing to a http request
// where the server has ended the socket.
var http = require('http');
var net = require('net');
var server = http.createServer(function(req, res) {
setImmediate(function() {
res.destroy();
});
});
server.listen(common.PORT, function() {
var req = http.request({
port: common.PORT,
path: '/',
method: 'POST'
});
var timer = setTimeout(write, 50);
var writes = 0;
function write() {
if (++writes === 128) {
clearTimeout(timer);
req.end();
test();
} else {
req.write('hello', function() {
timer = setImmediate(write);
});
}
}
var gotError = false;
var sawData = false;
var sawEnd = false;
req.on('error', function(er) {
assert(!gotError);
gotError = true;
switch (er.code) {
// This is the expected case
case 'ECONNRESET':
// On windows this sometimes manifests as ECONNABORTED
case 'ECONNABORTED':
// This test is timing sensitive so an EPIPE is not out of the question.
// It should be infrequent, given the 50 ms timeout, but not impossible.
case 'EPIPE':
break;
default:
assert.strictEqual(er.code,
'ECONNRESET',
'Writing to a torn down client should RESET or ABORT');
break;
}
clearTimeout(timer);
console.log('ECONNRESET was raised after %d writes', writes);
test();
});
req.on('response', function(res) {
res.on('data', function(chunk) {
console.error('saw data: ' + chunk);
sawData = true;
});
res.on('end', function() {
console.error('saw end');
sawEnd = true;
});
});
var closed = false;
function test() {
if (closed)
return;
server.close();
closed = true;
if (req.output.length || req.outputEncodings.length)
console.error('bad happened', req.output, req.outputEncodings);
assert.equal(req.output.length, 0);
assert.equal(req.outputEncodings, 0);
assert(gotError);
assert(!sawData);
assert(!sawEnd);
console.log('ok');
}
});