diff --git a/test/common/README.md b/test/common/README.md index 32ca6711573daa..1ec603a3bd8a02 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -338,6 +338,42 @@ The realpath of the 'tmp' directory. Name of the temp directory used by tests. +## Countdown Module + +The `Countdown` module provides a simple countdown mechanism for tests that +require a particular action to be taken after a given number of completed +tasks (for instance, shutting down an HTTP server after a specific number of +requests). + + +```js +const Countdown = require('../common/countdown'); + +function doSomething() { + console.log('.'); +} + +const countdown = new Countdown(2, doSomething); +countdown.dec(); +countdown.dec(); +``` + +### new Countdown(limit, callback) + +* `limit` {number} +* `callback` {function} + +Creates a new `Countdown` instance. + +### Countdown.prototype.dec() + +Decrements the `Countdown` counter. + +### Coutndown.prototype.remaining + +Specifies the remaining number of times `Countdown.prototype.dec()` must be +called before the callback is invoked. + ## WPT Module The wpt.js module is a port of parts of diff --git a/test/common/countdown.js b/test/common/countdown.js new file mode 100644 index 00000000000000..6a22be0a07eb0b --- /dev/null +++ b/test/common/countdown.js @@ -0,0 +1,27 @@ +/* eslint-disable required-modules */ +'use strict'; + +const assert = require('assert'); +const kLimit = Symbol('limit'); +const kCallback = Symbol('callback'); + +class Countdown { + constructor(limit, cb) { + assert.strictEqual(typeof limit, 'number'); + assert.strictEqual(typeof cb, 'function'); + this[kLimit] = limit; + this[kCallback] = cb; + } + + dec() { + assert(this[kLimit] > 0, 'Countdown expired'); + if (--this[kLimit] === 0) + this[kCallback](); + } + + get remaining() { + return this[kLimit]; + } +} + +module.exports = Countdown; diff --git a/test/parallel/test-common-countdown.js b/test/parallel/test-common-countdown.js new file mode 100644 index 00000000000000..ec0543f36fec74 --- /dev/null +++ b/test/parallel/test-common-countdown.js @@ -0,0 +1,15 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const Countdown = require('../common/countdown'); + +let done = ''; + +const countdown = new Countdown(2, common.mustCall(() => done = true)); +assert.strictEqual(countdown.remaining, 2); +countdown.dec(); +assert.strictEqual(countdown.remaining, 1); +countdown.dec(); +assert.strictEqual(countdown.remaining, 0); +assert.strictEqual(done, true); diff --git a/test/parallel/test-http-abort-client.js b/test/parallel/test-http-abort-client.js index 644b73f2c9995d..eda08ced97c55c 100644 --- a/test/parallel/test-http-abort-client.js +++ b/test/parallel/test-http-abort-client.js @@ -24,42 +24,24 @@ const common = require('../common'); const http = require('http'); let serverRes; -const server = http.Server(function(req, res) { - console.log('Server accepted request.'); +const server = http.Server((req, res) => { serverRes = res; res.writeHead(200); res.write('Part of my res.'); }); -server.listen(0, common.mustCall(function() { +server.listen(0, common.mustCall(() => { http.get({ - port: this.address().port, + port: server.address().port, headers: { connection: 'keep-alive' } - }, common.mustCall(function(res) { + }, common.mustCall((res) => { server.close(); serverRes.destroy(); - console.log(`Got res: ${res.statusCode}`); - console.dir(res.headers); - - res.on('data', function(chunk) { - console.log(`Read ${chunk.length} bytes`); - console.log(' chunk=%j', chunk.toString()); - }); - - res.on('end', function() { - console.log('Response ended.'); - }); - - res.on('aborted', function() { - console.log('Response aborted.'); - }); - - res.socket.on('close', function() { - console.log('socket closed, but not res'); - }); - - // it would be nice if this worked: + res.resume(); + res.on('end', common.mustCall()); + res.on('aborted', common.mustCall()); res.on('close', common.mustCall()); + res.socket.on('close', common.mustCall()); })); })); diff --git a/test/parallel/test-http-abort-queued.js b/test/parallel/test-http-abort-queued.js index 9b15fe2e7440a9..224d0b606ea744 100644 --- a/test/parallel/test-http-abort-queued.js +++ b/test/parallel/test-http-abort-queued.js @@ -20,13 +20,13 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); let complete; -const server = http.createServer(function(req, res) { +const server = http.createServer((req, res) => { // We should not see the queued /thatotherone request within the server // as it should be aborted before it is sent. assert.strictEqual(req.url, '/'); @@ -40,9 +40,7 @@ const server = http.createServer(function(req, res) { }); -server.listen(0, function() { - console.log('listen', server.address().port); - +server.listen(0, () => { const agent = new http.Agent({ maxSockets: 1 }); assert.strictEqual(Object.keys(agent.sockets).length, 0); @@ -55,7 +53,7 @@ server.listen(0, function() { }; const req1 = http.request(options); - req1.on('response', function(res1) { + req1.on('response', (res1) => { assert.strictEqual(Object.keys(agent.sockets).length, 1); assert.strictEqual(Object.keys(agent.requests).length, 0); @@ -69,7 +67,9 @@ server.listen(0, function() { assert.strictEqual(Object.keys(agent.sockets).length, 1); assert.strictEqual(Object.keys(agent.requests).length, 1); - req2.on('error', function(err) { + // TODO(jasnell): This event does not appear to currently be triggered. + // is this handler actually required? + req2.on('error', (err) => { // This is expected in response to our explicit abort call assert.strictEqual(err.code, 'ECONNRESET'); }); @@ -80,25 +80,16 @@ server.listen(0, function() { assert.strictEqual(Object.keys(agent.sockets).length, 1); assert.strictEqual(Object.keys(agent.requests).length, 1); - console.log(`Got res: ${res1.statusCode}`); - console.dir(res1.headers); - - res1.on('data', function(chunk) { - console.log(`Read ${chunk.length} bytes`); - console.log(' chunk=%j', chunk.toString()); - complete(); - }); + res1.on('data', (chunk) => complete()); - res1.on('end', function() { - console.log('Response ended.'); - - setTimeout(function() { + res1.on('end', common.mustCall(() => { + setTimeout(common.mustCall(() => { assert.strictEqual(Object.keys(agent.sockets).length, 0); assert.strictEqual(Object.keys(agent.requests).length, 0); server.close(); - }, 100); - }); + }), 100); + })); }); req1.end(); diff --git a/test/parallel/test-http-abort-stream-end.js b/test/parallel/test-http-abort-stream-end.js index ea14fe0ca99a74..8d2704a1ee7d17 100644 --- a/test/parallel/test-http-abort-stream-end.js +++ b/test/parallel/test-http-abort-stream-end.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); @@ -28,20 +28,21 @@ const http = require('http'); const maxSize = 1024; let size = 0; -const s = http.createServer(function(req, res) { - this.close(); +const server = http.createServer(common.mustCall((req, res) => { + server.close(); res.writeHead(200, { 'Content-Type': 'text/plain' }); for (let i = 0; i < maxSize; i++) { - res.write('x' + i); + res.write(`x${i}`); } res.end(); -}); +})); let aborted = false; -s.listen(0, function() { - const req = http.get('http://localhost:' + s.address().port, function(res) { - res.on('data', function(chunk) { +server.listen(0, () => { + + const res = common.mustCall((res) => { + res.on('data', (chunk) => { size += chunk.length; assert(!aborted, 'got data after abort'); if (size > maxSize) { @@ -50,11 +51,9 @@ s.listen(0, function() { size = maxSize; } }); + + req.on('abort', common.mustCall(() => assert.strictEqual(size, maxSize))); }); -}); -process.on('exit', function() { - assert(aborted); - assert.strictEqual(size, maxSize); - console.log('ok'); + const req = http.get(`http://localhost:${server.address().port}`, res); }); diff --git a/test/parallel/test-http-after-connect.js b/test/parallel/test-http-after-connect.js index d8a711c8d69a26..324186bab72324 100644 --- a/test/parallel/test-http-after-connect.js +++ b/test/parallel/test-http-after-connect.js @@ -23,61 +23,51 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); -let clientResponses = 0; - -const server = http.createServer(common.mustCall(function(req, res) { - console.error('Server got GET request'); +const server = http.createServer(common.mustCall((req, res) => { req.resume(); res.writeHead(200); res.write(''); - setTimeout(function() { - res.end(req.url); - }, 50); + setTimeout(() => res.end(req.url), 50); }, 2)); -server.on('connect', common.mustCall(function(req, socket) { - console.error('Server got CONNECT request'); + +const countdown = new Countdown(2, common.mustCall(() => server.close())); + +server.on('connect', common.mustCall((req, socket) => { socket.write('HTTP/1.1 200 Connection established\r\n\r\n'); socket.resume(); - socket.on('end', function() { - socket.end(); - }); + socket.on('end', () => socket.end()); })); -server.listen(0, function() { + +server.listen(0, common.mustCall(() => { const req = http.request({ - port: this.address().port, + port: server.address().port, method: 'CONNECT', path: 'google.com:80' }); - req.on('connect', common.mustCall(function(res, socket) { - console.error('Client got CONNECT response'); + req.on('connect', common.mustCall((res, socket) => { socket.end(); - socket.on('end', function() { + socket.on('end', common.mustCall(() => { doRequest(0); doRequest(1); - }); + })); socket.resume(); })); req.end(); -}); +})); function doRequest(i) { http.get({ port: server.address().port, path: `/request${i}` - }, common.mustCall(function(res) { - console.error('Client got GET response'); + }, common.mustCall((res) => { let data = ''; res.setEncoding('utf8'); - res.on('data', function(chunk) { - data += chunk; - }); - res.on('end', function() { + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => { assert.strictEqual(data, `/request${i}`); - ++clientResponses; - if (clientResponses === 2) { - server.close(); - } - }); + countdown.dec(); + })); })); } diff --git a/test/parallel/test-http-agent-destroyed-socket.js b/test/parallel/test-http-agent-destroyed-socket.js index 163664b7bd7c72..7970ce8bae0fcb 100644 --- a/test/parallel/test-http-agent-destroyed-socket.js +++ b/test/parallel/test-http-agent-destroyed-socket.js @@ -23,35 +23,30 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); -}).listen(0, common.mustCall(function() { +}, 2)).listen(0, common.mustCall(() => { const agent = new http.Agent({ maxSockets: 1 }); - agent.on('free', function(socket) { - console.log('freeing socket. destroyed? ', socket.destroyed); - }); + agent.on('free', common.mustCall(3)); const requestOptions = { agent: agent, host: 'localhost', - port: this.address().port, + port: server.address().port, path: '/' }; - const request1 = http.get(requestOptions, common.mustCall(function(response) { + const request1 = http.get(requestOptions, common.mustCall((response) => { // assert request2 is queued in the agent const key = agent.getName(requestOptions); assert.strictEqual(agent.requests[key].length, 1); - console.log('got response1'); - request1.socket.on('close', function() { - console.log('request1 socket closed'); - }); - response.pipe(process.stdout); - response.on('end', common.mustCall(function() { - console.log('response1 done'); + request1.socket.on('close', common.mustCall()); + response.resume(); + response.on('end', common.mustCall(() => { ///////////////////////////////// // // THE IMPORTANT PART @@ -65,43 +60,29 @@ const server = http.createServer(function(req, res) { // is triggered. request1.socket.destroy(); - response.once('close', function() { + // TODO(jasnell): This close event does not appear to be triggered. + // is it necessary? + response.once('close', () => { // assert request2 was removed from the queue assert(!agent.requests[key]); - console.log("waiting for request2.onSocket's nextTick"); - process.nextTick(common.mustCall(function() { + process.nextTick(() => { // assert that the same socket was not assigned to request2, // since it was destroyed. assert.notStrictEqual(request1.socket, request2.socket); assert(!request2.socket.destroyed, 'the socket is destroyed'); - })); + }); }); })); })); - const request2 = http.get(requestOptions, common.mustCall(function(response) { + const request2 = http.get(requestOptions, common.mustCall((response) => { assert(!request2.socket.destroyed); assert(request1.socket.destroyed); // assert not reusing the same socket, since it was destroyed. assert.notStrictEqual(request1.socket, request2.socket); - console.log('got response2'); - let gotClose = false; - let gotResponseEnd = false; - request2.socket.on('close', function() { - console.log('request2 socket closed'); - gotClose = true; - done(); - }); - response.pipe(process.stdout); - response.on('end', function() { - console.log('response2 done'); - gotResponseEnd = true; - done(); - }); - - function done() { - if (gotResponseEnd && gotClose) - server.close(); - } + const countdown = new Countdown(2, common.mustCall(() => server.close())); + request2.socket.on('close', common.mustCall(() => countdown.dec())); + response.on('end', common.mustCall(() => countdown.dec())); + response.resume(); })); })); diff --git a/test/parallel/test-http-agent-error-on-idle.js b/test/parallel/test-http-agent-error-on-idle.js index 2f270c0d30ca0b..fce5e8f0324f5c 100644 --- a/test/parallel/test-http-agent-error-on-idle.js +++ b/test/parallel/test-http-agent-error-on-idle.js @@ -1,32 +1,31 @@ 'use strict'; -require('../common'); + +const common = require('../common'); const assert = require('assert'); const http = require('http'); const Agent = http.Agent; -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); -}); +}, 2)); -server.listen(0, function() { - const agent = new Agent({ - keepAlive: true, - }); +server.listen(0, () => { + const agent = new Agent({ keepAlive: true }); const requestParams = { host: 'localhost', - port: this.address().port, + port: server.address().port, agent: agent, path: '/' }; const socketKey = agent.getName(requestParams); - get(function(res) { + http.get(requestParams, common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); res.resume(); - res.on('end', function() { - process.nextTick(function() { + res.on('end', common.mustCall(() => { + process.nextTick(common.mustCall(() => { const freeSockets = agent.freeSockets[socketKey]; assert.strictEqual(freeSockets.length, 1, `expect a free socket on ${socketKey}`); @@ -35,14 +34,10 @@ server.listen(0, function() { const freeSocket = freeSockets[0]; freeSocket.emit('error', new Error('ECONNRESET: test')); - get(done); - }); - }); - }); - - function get(callback) { - return http.get(requestParams, callback); - } + http.get(requestParams, done); + })); + })); + })); function done() { assert.strictEqual(Object.keys(agent.freeSockets).length, 0, @@ -50,6 +45,5 @@ server.listen(0, function() { agent.destroy(); server.close(); - process.exit(0); } }); diff --git a/test/parallel/test-http-agent-false.js b/test/parallel/test-http-agent-false.js index 0e633c7c103b76..4d92d5e01e03e2 100644 --- a/test/parallel/test-http-agent-false.js +++ b/test/parallel/test-http-agent-false.js @@ -20,8 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); -const assert = require('assert'); +const common = require('../common'); const http = require('http'); // sending `agent: false` when `port: null` is also passed in (i.e. the result @@ -35,20 +34,13 @@ const opts = { agent: false }; -let good = false; -process.on('exit', function() { - assert(good, 'expected either an "error" or "response" event'); -}); - // we just want an "error" (no local HTTP server on port 80) or "response" // to happen (user happens ot have HTTP server running on port 80). // As long as the process doesn't crash from a C++ assertion then we're good. const req = http.request(opts); -req.on('response', function(res) { - good = true; -}); -req.on('error', function(err) { - // an "error" event is ok, don't crash the process - good = true; -}); + +// Will be called by either the response event or error event, not both +const oneResponse = common.mustCall(); +req.on('response', oneResponse); +req.on('error', oneResponse); req.end(); diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index c695b55bfa5ee7..2c8b6c1cc98d2d 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -34,19 +34,17 @@ const agent = new Agent({ maxFreeSockets: 5 }); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { if (req.url === '/error') { res.destroy(); return; } else if (req.url === '/remote_close') { // cache the socket, close it after a short delay const socket = res.connection; - setImmediate(function() { - socket.end(); - }); + setImmediate(common.mustCall(() => socket.end())); } res.end('hello world'); -}); +}, 4)); function get(path, callback) { return http.get({ @@ -65,82 +63,75 @@ function checkDataAndSockets(body) { function second() { // request second, use the same socket - get('/second', function(res) { + get('/second', common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); res.on('data', checkDataAndSockets); - res.on('end', function() { + res.on('end', common.mustCall(() => { assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); - process.nextTick(function() { + process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); remoteClose(); - }); - }); - }); + })); + })); + })); } function remoteClose() { // mock remote server close the socket - get('/remote_close', function(res) { + get('/remote_close', common.mustCall((res) => { assert.deepStrictEqual(res.statusCode, 200); res.on('data', checkDataAndSockets); - res.on('end', function() { + res.on('end', common.mustCall(() => { assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); - process.nextTick(function() { + process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); // waitting remote server close the socket - setTimeout(function() { + setTimeout(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name], undefined, 'freeSockets is not empty'); remoteError(); - }, common.platformTimeout(200)); - }); - }); - }); + }), common.platformTimeout(200)); + })); + })); + })); } function remoteError() { // remove server will destroy ths socket - const req = get('/error', function(res) { - throw new Error('should not call this function'); - }); - req.on('error', function(err) { - assert.ok(err); + const req = get('/error', common.mustNotCall()); + req.on('error', common.mustCall((err) => { + assert(err); assert.strictEqual(err.message, 'socket hang up'); assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); // Wait socket 'close' event emit - setTimeout(function() { + setTimeout(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name], undefined); - done(); - }, common.platformTimeout(1)); - }); -} - -function done() { - console.log('http keepalive agent test success.'); - process.exit(0); + server.close(); + }), common.platformTimeout(1)); + })); } -server.listen(0, function() { +server.listen(0, common.mustCall(() => { name = `localhost:${server.address().port}:`; // request first, and keep alive - get('/first', function(res) { + get('/first', common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); res.on('data', checkDataAndSockets); - res.on('end', function() { + res.on('end', common.mustCall(() => { assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); - process.nextTick(function() { + process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); second(); - }); - }); - }); -}); + })); + })); + })); +})); diff --git a/test/parallel/test-http-agent-maxsockets-regress-4050.js b/test/parallel/test-http-agent-maxsockets-regress-4050.js index fd3a8c33f3e39a..57a90e4b05c79f 100644 --- a/test/parallel/test-http-agent-maxsockets-regress-4050.js +++ b/test/parallel/test-http-agent-maxsockets-regress-4050.js @@ -1,7 +1,8 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const MAX_SOCKETS = 2; @@ -12,9 +13,11 @@ const agent = new http.Agent({ maxFreeSockets: 2 }); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); -}); +}, 6)); + +const countdown = new Countdown(6, common.mustCall(() => server.close())); function get(path, callback) { return http.get({ @@ -25,19 +28,14 @@ function get(path, callback) { }, callback); } -server.listen(0, function() { - let finished = 0; - const num_requests = 6; - for (let i = 0; i < num_requests; i++) { - const request = get('/1', function() { - }); - request.on('response', function() { +server.listen(0, common.mustCall(() => { + for (let i = 0; i < 6; i++) { + const request = get('/1', common.mustCall()); + request.on('response', common.mustCall(() => { request.abort(); const sockets = agent.sockets[Object.keys(agent.sockets)[0]]; assert(sockets.length <= MAX_SOCKETS); - if (++finished === num_requests) { - server.close(); - } - }); + countdown.dec(); + })); } -}); +})); diff --git a/test/parallel/test-http-agent-maxsockets.js b/test/parallel/test-http-agent-maxsockets.js index 513906160048d9..66fffba250513f 100644 --- a/test/parallel/test-http-agent-maxsockets.js +++ b/test/parallel/test-http-agent-maxsockets.js @@ -1,7 +1,8 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const agent = new http.Agent({ keepAlive: true, @@ -10,9 +11,9 @@ const agent = new http.Agent({ maxFreeSockets: 2 }); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); -}); +}, 2)); function get(path, callback) { return http.get({ @@ -23,32 +24,25 @@ function get(path, callback) { }, callback); } -let count = 0; -function done() { - if (++count !== 2) { - return; - } +const countdown = new Countdown(2, common.mustCall(() => { const freepool = agent.freeSockets[Object.keys(agent.freeSockets)[0]]; assert.strictEqual(freepool.length, 2, `expect keep 2 free sockets, but got ${freepool.length}`); agent.destroy(); server.close(); +})); + +function dec() { + process.nextTick(() => countdown.dec()); } -server.listen(0, function() { - get('/1', function(res) { - assert.strictEqual(res.statusCode, 200); - res.resume(); - res.on('end', function() { - process.nextTick(done); - }); - }); +function onGet(res) { + assert.strictEqual(res.statusCode, 200); + res.resume(); + res.on('end', common.mustCall(dec)); +} - get('/2', function(res) { - assert.strictEqual(res.statusCode, 200); - res.resume(); - res.on('end', function() { - process.nextTick(done); - }); - }); -}); +server.listen(0, common.mustCall(() => { + get('/1', common.mustCall(onGet)); + get('/2', common.mustCall(onGet)); +})); diff --git a/test/parallel/test-http-agent-no-protocol.js b/test/parallel/test-http-agent-no-protocol.js index 4630ef8ee6388d..b5a144abc93d9e 100644 --- a/test/parallel/test-http-agent-no-protocol.js +++ b/test/parallel/test-http-agent-no-protocol.js @@ -24,17 +24,17 @@ const common = require('../common'); const http = require('http'); const url = require('url'); -const server = http.createServer(common.mustCall(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end(); -})).listen(0, '127.0.0.1', common.mustCall(function() { - const opts = url.parse(`http://127.0.0.1:${this.address().port}/`); +})).listen(0, '127.0.0.1', common.mustCall(() => { + const opts = url.parse(`http://127.0.0.1:${server.address().port}/`); // remove the `protocol` field… the `http` module should fall back // to "http:", as defined by the global, default `http.Agent` instance. opts.agent = new http.Agent(); opts.agent.protocol = null; - http.get(opts, common.mustCall(function(res) { + http.get(opts, common.mustCall((res) => { res.resume(); server.close(); })); diff --git a/test/parallel/test-http-agent-null.js b/test/parallel/test-http-agent-null.js index 784dc32211c807..0f87d098134b50 100644 --- a/test/parallel/test-http-agent-null.js +++ b/test/parallel/test-http-agent-null.js @@ -23,14 +23,14 @@ const common = require('../common'); const http = require('http'); -const server = http.createServer(common.mustCall(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end(); -})).listen(0, common.mustCall(function() { +})).listen(0, common.mustCall(() => { const options = { agent: null, - port: this.address().port + port: server.address().port }; - http.get(options, common.mustCall(function(res) { + http.get(options, common.mustCall((res) => { res.resume(); server.close(); })); diff --git a/test/parallel/test-http-automatic-headers.js b/test/parallel/test-http-automatic-headers.js index 37a5c43901c33d..5a6a8e524c76ee 100644 --- a/test/parallel/test-http-automatic-headers.js +++ b/test/parallel/test-http-automatic-headers.js @@ -1,23 +1,23 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.setHeader('X-Date', 'foo'); res.setHeader('X-Connection', 'bar'); res.setHeader('X-Content-Length', 'baz'); res.end(); -}); +})); server.listen(0); -server.on('listening', function() { - const agent = new http.Agent({ port: this.address().port, maxSockets: 1 }); +server.on('listening', common.mustCall(() => { + const agent = new http.Agent({ port: server.address().port, maxSockets: 1 }); http.get({ - port: this.address().port, + port: server.address().port, path: '/hello', agent: agent - }, function(res) { + }, common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); assert.strictEqual(res.headers['x-date'], 'foo'); assert.strictEqual(res.headers['x-connection'], 'bar'); @@ -27,5 +27,5 @@ server.on('listening', function() { assert.strictEqual(res.headers['content-length'], '0'); server.close(); agent.destroy(); - }); -}); + })); +})); diff --git a/test/parallel/test-http-blank-header.js b/test/parallel/test-http-blank-header.js index 1659dc5ed5fd5d..ff86193a1bad4a 100644 --- a/test/parallel/test-http-blank-header.js +++ b/test/parallel/test-http-blank-header.js @@ -25,34 +25,29 @@ const assert = require('assert'); const http = require('http'); const net = require('net'); -const server = http.createServer(common.mustCall(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { assert.strictEqual('GET', req.method); assert.strictEqual('/blah', req.url); assert.deepStrictEqual({ - host: 'mapdevel.trolologames.ru:443', - origin: 'http://mapdevel.trolologames.ru', + host: 'example.org:443', + origin: 'http://example.org', cookie: '' }, req.headers); })); -server.listen(0, function() { - const c = net.createConnection(this.address().port); +server.listen(0, common.mustCall(() => { + const c = net.createConnection(server.address().port); - c.on('connect', function() { + c.on('connect', common.mustCall(() => { c.write('GET /blah HTTP/1.1\r\n' + - 'Host: mapdevel.trolologames.ru:443\r\n' + + 'Host: example.org:443\r\n' + 'Cookie:\r\n' + - 'Origin: http://mapdevel.trolologames.ru\r\n' + + 'Origin: http://example.org\r\n' + '\r\n\r\nhello world' ); - }); + })); - c.on('end', function() { - c.end(); - }); - - c.on('close', function() { - server.close(); - }); -}); + c.on('end', common.mustCall(() => c.end())); + c.on('close', common.mustCall(() => server.close())); +})); diff --git a/test/parallel/test-http-buffer-sanity.js b/test/parallel/test-http-buffer-sanity.js index a72d326d6f4107..8dfccf7d5c688d 100644 --- a/test/parallel/test-http-buffer-sanity.js +++ b/test/parallel/test-http-buffer-sanity.js @@ -32,16 +32,12 @@ for (let i = 0; i < buffer.length; i++) { buffer[i] = i % 256; } - -const web = http.Server(function(req, res) { - web.close(); - - console.log(req.headers); +const server = http.Server(function(req, res) { + server.close(); let i = 0; - req.on('data', function(d) { - process.stdout.write(','); + req.on('data', (d) => { measuredSize += d.length; for (let j = 0; j < d.length; j++) { assert.strictEqual(buffer[i], d[j]); @@ -49,39 +45,27 @@ const web = http.Server(function(req, res) { } }); - - req.on('end', function() { + req.on('end', common.mustCall(() => { + assert.strictEqual(bufferSize, measuredSize); res.writeHead(200); res.write('thanks'); res.end(); - console.log('response with \'thanks\''); - }); - - req.connection.on('error', function(e) { - console.log(`http server-side error: ${e.message}`); - process.exit(1); - }); + })); }); -web.listen(0, common.mustCall(function() { - console.log('Making request'); - +server.listen(0, common.mustCall(() => { const req = http.request({ - port: this.address().port, - method: 'GET', + port: server.address().port, + method: 'POST', path: '/', headers: { 'content-length': buffer.length } - }, common.mustCall(function(res) { - console.log('Got response'); + }, common.mustCall((res) => { res.setEncoding('utf8'); - res.on('data', common.mustCall(function(string) { - assert.strictEqual('thanks', string); + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => { + assert.strictEqual('thanks', data); })); })); req.end(buffer); })); - - -process.on('exit', function() { - assert.strictEqual(bufferSize, measuredSize); -}); diff --git a/test/parallel/test-http-chunked.js b/test/parallel/test-http-chunked.js index d587141c6df5b1..9ae2932a5c4149 100644 --- a/test/parallel/test-http-chunked.js +++ b/test/parallel/test-http-chunked.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); @@ -34,31 +34,23 @@ const UTF8_STRING = '南越国是前203年至前111年存在于岭南地区的 '采用封建制和郡县制并存的制度,它的建立保证了秦末乱世岭南地区社会秩序的稳定,' + '有效的改善了岭南地区落后的政治、经济现状。'; -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf8' }); res.end(UTF8_STRING, 'utf8'); -}); -server.listen(0, function() { +})); +server.listen(0, common.mustCall(() => { let data = ''; - const get = http.get({ + http.get({ path: '/', host: 'localhost', - port: this.address().port - }, function(x) { + port: server.address().port + }, common.mustCall((x) => { x.setEncoding('utf8'); - x.on('data', function(c) { data += c; }); - x.on('error', function(e) { - throw e; - }); - x.on('end', function() { + x.on('data', (c) => data += c); + x.on('end', common.mustCall(() => { assert.strictEqual('string', typeof data); - console.log('here is the response:'); assert.strictEqual(UTF8_STRING, data); - console.log(data); server.close(); - }); - }); - get.on('error', function(e) { throw e; }); - get.end(); - -}); + })); + })).end(); +})); diff --git a/test/parallel/test-http-client-abort.js b/test/parallel/test-http-client-abort.js index eaf4a05e6f49f1..71fd2ad64cabdd 100644 --- a/test/parallel/test-http-client-abort.js +++ b/test/parallel/test-http-client-abort.js @@ -20,57 +20,35 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); -const assert = require('assert'); +const common = require('../common'); const http = require('http'); +const Countdown = require('../common/countdown'); -let clientAborts = 0; +const N = 8; + +const countdown = new Countdown(N, common.mustCall(() => server.close())); -const server = http.Server(function(req, res) { - console.log('Got connection'); +const server = http.Server(common.mustCall((req, res) => { res.writeHead(200); res.write('Working on it...'); + req.on('aborted', common.mustCall(() => countdown.dec())); +}, N)); - // I would expect an error event from req or res that the client aborted - // before completing the HTTP request / response cycle, or maybe a new - // event like "aborted" or something. - req.on('aborted', function() { - clientAborts++; - console.log(`Got abort ${clientAborts}`); - if (clientAborts === N) { - console.log('All aborts detected, you win.'); - server.close(); - } - }); -}); +server.listen(0, common.mustCall(() => { -let responses = 0; -const N = 8; -const requests = []; + const requests = []; + const reqCountdown = new Countdown(N, common.mustCall(() => { + requests.forEach((req) => req.abort()); + })); -server.listen(0, function() { - console.log('Server listening.'); + const options = { port: server.address().port }; for (let i = 0; i < N; i++) { - console.log(`Making client ${i}`); - const options = { port: this.address().port, path: `/?id=${i}` }; - const req = http.get(options, function(res) { - console.log(`Client response code ${res.statusCode}`); - - res.resume(); - if (++responses === N) { - console.log('All clients connected, destroying.'); - requests.forEach(function(outReq) { - console.log('abort'); - outReq.abort(); - }); - } - }); - - requests.push(req); + options.path = `/?id=${i}`; + requests.push( + http.get(options, common.mustCall((res) => { + res.resume(); + reqCountdown.dec(); + }))); } -}); - -process.on('exit', function() { - assert.strictEqual(N, clientAborts); -}); +})); diff --git a/test/parallel/test-http-client-abort2.js b/test/parallel/test-http-client-abort2.js index e6804897ea2138..bc4b0e40838b36 100644 --- a/test/parallel/test-http-client-abort2.js +++ b/test/parallel/test-http-client-abort2.js @@ -20,18 +20,19 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const http = require('http'); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('Hello'); -}); +})); -server.listen(0, function() { - const req = http.get({ port: this.address().port }, function(res) { - res.on('data', function(data) { +server.listen(0, common.mustCall(() => { + const options = { port: server.address().port }; + const req = http.get(options, common.mustCall((res) => { + res.on('data', (data) => { req.abort(); server.close(); }); - }); -}); + })); +})); diff --git a/test/parallel/test-http-client-agent.js b/test/parallel/test-http-client-agent.js index 1a3c099d4df897..f2d1b612b5af82 100644 --- a/test/parallel/test-http-client-agent.js +++ b/test/parallel/test-http-client-agent.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); @@ -28,23 +28,22 @@ let name; const max = 3; let count = 0; -const server = http.Server(function(req, res) { +const server = http.Server(common.mustCall((req, res) => { if (req.url === '/0') { - setTimeout(function() { + setTimeout(common.mustCall(() => { res.writeHead(200); res.end('Hello, World!'); - }, 100); + }), 100); } else { res.writeHead(200); res.end('Hello, World!'); } -}); -server.listen(0, function() { - name = http.globalAgent.getName({ port: this.address().port }); - for (let i = 0; i < max; ++i) { +}, max)); +server.listen(0, common.mustCall(() => { + name = http.globalAgent.getName({ port: server.address().port }); + for (let i = 0; i < max; ++i) request(i); - } -}); +})); function request(i) { const req = http.get({ @@ -52,7 +51,7 @@ function request(i) { path: `/${i}` }, function(res) { const socket = req.socket; - socket.on('close', function() { + socket.on('close', common.mustCall(() => { ++count; if (count < max) { assert.strictEqual(http.globalAgent.sockets[name].includes(socket), @@ -62,11 +61,7 @@ function request(i) { assert(!http.globalAgent.requests.hasOwnProperty(name)); server.close(); } - }); + })); res.resume(); }); } - -process.on('exit', function() { - assert.strictEqual(count, max); -}); diff --git a/test/parallel/test-http-client-check-http-token.js b/test/parallel/test-http-client-check-http-token.js index b28af938f9b9ef..4fa3a44802a5f0 100644 --- a/test/parallel/test-http-client-check-http-token.js +++ b/test/parallel/test-http-client-check-http-token.js @@ -2,39 +2,28 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const expectedSuccesses = [undefined, null, 'GET', 'post']; -let requestCount = 0; +const expectedFails = [-1, 1, 0, {}, true, false, [], Symbol()]; -const server = http.createServer((req, res) => { - requestCount++; - res.end(); +const countdown = + new Countdown(expectedSuccesses.length, + common.mustCall(() => server.close())); - if (expectedSuccesses.length === requestCount) { - server.close(); - } -}).listen(0, test); +const server = http.createServer(common.mustCall((req, res) => { + res.end(); + countdown.dec(); +}, expectedSuccesses.length)); -function test() { - function fail(input) { +server.listen(0, common.mustCall(() => { + expectedFails.forEach((method) => { assert.throws(() => { - http.request({ method: input, path: '/' }, common.mustNotCall()); + http.request({ method, path: '/' }, common.mustNotCall()); }, /^TypeError: Method must be a string$/); - } - - fail(-1); - fail(1); - fail(0); - fail({}); - fail(true); - fail(false); - fail([]); - - function ok(method) { - http.request({ method: method, port: server.address().port }).end(); - } + }); expectedSuccesses.forEach((method) => { - ok(method); + http.request({ method, port: server.address().port }).end(); }); -} +})); diff --git a/test/parallel/test-http-client-default-headers-exist.js b/test/parallel/test-http-client-default-headers-exist.js index 05dd509e19e6af..e0cf82e46220c4 100644 --- a/test/parallel/test-http-client-default-headers-exist.js +++ b/test/parallel/test-http-client-default-headers-exist.js @@ -20,9 +20,10 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const expectedHeaders = { 'DELETE': ['host', 'connection'], @@ -35,17 +36,18 @@ const expectedHeaders = { const expectedMethods = Object.keys(expectedHeaders); -let requestCount = 0; +const countdown = + new Countdown(expectedMethods.length, + common.mustCall(() => server.close())); -const server = http.createServer(function(req, res) { - requestCount++; +const server = http.createServer(common.mustCall((req, res) => { res.end(); assert(expectedHeaders.hasOwnProperty(req.method), `${req.method} was an unexpected method`); const requestHeaders = Object.keys(req.headers); - requestHeaders.forEach(function(header) { + requestHeaders.forEach((header) => { assert.strictEqual( expectedHeaders[req.method].includes(header.toLowerCase()), true, @@ -59,15 +61,14 @@ const server = http.createServer(function(req, res) { `some headers were missing for method: ${req.method}` ); - if (expectedMethods.length === requestCount) - server.close(); -}); + countdown.dec(); +}, expectedMethods.length)); -server.listen(0, function() { - expectedMethods.forEach(function(method) { +server.listen(0, common.mustCall(() => { + expectedMethods.forEach((method) => { http.request({ method: method, port: server.address().port }).end(); }); -}); +})); diff --git a/test/parallel/test-http-client-encoding.js b/test/parallel/test-http-client-encoding.js index 8e795481af7289..a4701cdbd0abb1 100644 --- a/test/parallel/test-http-client-encoding.js +++ b/test/parallel/test-http-client-encoding.js @@ -20,20 +20,20 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); - +const common = require('../common'); +const assert = require('assert'); const http = require('http'); -http.createServer(function(req, res) { - res.end('ok\n'); - this.close(); -}).listen(0, test); - -function test() { +const server = http.createServer((req, res) => { + res.end('ok'); + server.close(); +}).listen(0, common.mustCall(() => { http.request({ - port: this.address().port, + port: server.address().port, encoding: 'utf8' - }, function(res) { - res.pipe(process.stdout); - }).end(); -} + }, common.mustCall((res) => { + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => assert.strictEqual(data, 'ok'))); + })).end(); +})); diff --git a/test/parallel/test-http-client-parse-error.js b/test/parallel/test-http-client-parse-error.js index 074f24063f5fe4..60f1ee45c8efc1 100644 --- a/test/parallel/test-http-client-parse-error.js +++ b/test/parallel/test-http-client-parse-error.js @@ -20,41 +20,33 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -require('../common'); -const assert = require('assert'); - +const common = require('../common'); const http = require('http'); const net = require('net'); +const Countdown = require('../common/countdown'); + +const countdown = new Countdown(2, common.mustCall(() => server.close())); -let connects = 0; -let parseErrors = 0; +const payloads = [ + 'HTTP/1.1 302 Object Moved\r\nContent-Length: 0\r\n\r\nhi world', + 'bad http = should trigger parse error' +]; // Create a TCP server -net.createServer(function(c) { - console.log('connection'); - if (++connects === 1) { - c.end('HTTP/1.1 302 Object Moved\r\nContent-Length: 0\r\n\r\nhi world'); - } else { - c.end('bad http - should trigger parse error\r\n'); - this.close(); - } -}).listen(0, '127.0.0.1', function() { +const server = + net.createServer(common.mustCall((c) => c.end(payloads.shift()), 2)); + +server.listen(0, common.mustCall(() => { for (let i = 0; i < 2; i++) { - http.request({ - host: '127.0.0.1', - port: this.address().port, - method: 'GET', + http.get({ + port: server.address().port, path: '/' - }).on('error', function(e) { - console.log('got error from client'); - assert.ok(e.message.includes('Parse Error')); - assert.strictEqual(e.code, 'HPE_INVALID_CONSTANT'); - parseErrors++; - }).end(); + }).on('error', common.mustCall((e) => { + common.expectsError({ + code: 'HPE_INVALID_CONSTANT', + message: 'Parse Error' + })(e); + countdown.dec(); + })); } -}); - -process.on('exit', function() { - assert.strictEqual(connects, 2); - assert.strictEqual(parseErrors, 2); -}); +}));