From 13e1131406b2239f99962ecc05b8179aa781d0f8 Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Wed, 18 Mar 2015 04:12:16 -0400 Subject: [PATCH] test: address timing issues in simple http tests simple tests test-http-request-end.js, test-http-default-encoding.js hangs in AIX. The root cause for both the failures is related to the timing with which packets are sent between the client and server. On the client side, one factor that affects the timing is Nagle's algorithm. With Nagle enabled there may be a delay between two packets as the stack may wait until either: a. An acknowledgement for the first packet is received, or b. 200 ms elapses. before sending the second packet. Similarly at the server side 2 sequential packages can be delivered to the application either together or separatly. On AIX we see that they are delivered separately to the server, while on Linux delivered together. If we change the timing, for example disabling Nagle on AIX we see the 2 packets delivered together and the tests pass. In the test case simple/test-http-request-end.js, the client request handler of the server receives and stores the data in a data callback, closes the server in a request end callback, and writes to the client and ends the response, in-line with the request receipt. An HTTP parser module parses the incoming message, and invokes callback routines which are registered for HTTP events (such as header, body, end etc.) Because the termination sequence arrive in a separate packet, there is a delay in parsing that message and identify that the client request ended (and thereby invoke the request end call backhandler). Due to this delay, the response close happens first, which in-turn destroys the server socket leading to the fd and watcher removal from the uv loop abandoning further events on this connection, and end call back never being called, causing the reported hang. simple/test-http-default-encoding.js suffers from the same problem. Also, remove the timer logic from the test case. Test harness anyways contain a timer which controls the individual tests so remove such controls from the test case, as suggested by @tjfontaine Reviewed-By: Michael Dawson PR-URL: https://github.com/joyent/node/pull/9432 --- test/simple/test-http-default-encoding.js | 9 ++------- test/simple/test-http-request-end.js | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/test/simple/test-http-default-encoding.js b/test/simple/test-http-default-encoding.js index b06f7c83a20472..d2c342c244cd2f 100644 --- a/test/simple/test-http-default-encoding.js +++ b/test/simple/test-http-default-encoding.js @@ -31,16 +31,11 @@ var server = http.Server(function(req, res) { req.on('data', function(chunk) { result += chunk; }).on('end', function() { - clearTimeout(timeout); server.close(); + res.writeHead(200); + res.end('hello world\n'); }); - var timeout = setTimeout(function() { - process.exit(1); - }, 100); - - res.writeHead(200); - res.end('hello world\n'); }); server.listen(common.PORT, function() { diff --git a/test/simple/test-http-request-end.js b/test/simple/test-http-request-end.js index f64dcc305adaa0..a4cd61a3fa98f1 100644 --- a/test/simple/test-http-request-end.js +++ b/test/simple/test-http-request-end.js @@ -34,10 +34,10 @@ var server = http.Server(function(req, res) { req.on('end', function() { server.close(); + res.writeHead(200); + res.end('hello world\n'); }); - res.writeHead(200); - res.end('hello world\n'); }); server.listen(common.PORT, function() {