Open mattdeluco opened 6 years ago
I figured out that passing a function to supertest.agent()
will always cause supertest to bind to an ephemeral port on every request - the express app
being a function.
Instead, I had to export the result of app.listen()
(a NodeJS http.Server
object) and pass that to supertest.agent()
:
app.js
...
let server = app.listen(process.env.PORT, function () {
logger.info('App listening on port ' + process.env.PORT);
});
module.exports = server;
test.js
let server = require('../app.js'),
agent = require('supertest').agent(server),
...
Now supertest opens a new socket for every request, but they all go to the same port on the server side.
Is it possible to reuse the sockets? Or have them close cleanly so they're not hanging around?
I was able to set the http agent in superagent by wrapping the various HTTP verb method calls and then setting the agent. Combined with passing the http server returned from express app.listen this should give you a configurable number of sockets in a pool that make requests.
Here's the code I used to set the HTTP socket pool to 10 as well as reversing the cookie saving behavior of supertest when you set an agent.
` const http = require("http"); const keepAliveAgent = new http.Agent({ keepAlive: true, keepAliveMsecs: 90000, timeout: 1200000, maxSockets:10, maxFreeSockets:10 }); const _request = request.agent(app.app); _request.saveCookies = .noop;
['get', 'post', 'put', 'del', 'delete', 'head'].forEach((method)=>{ let fx = _request[method];
_request[method] = (...args)=>{
let result = fx.call(_request, ...args);
result.agent(keepAliveAgent);
return result;
};
}); `
Apparently this is solved.
https://stackoverflow.com/a/62278976/1548557
app.listen
call from the place you are currently passing to supertest..listen
on the port you desire.Alternatively, you can litter the code with test-specific logic as shown in another example https://stackoverflow.com/a/63293781/1548557 , but it just boils down to the above, which I think is cleaner.
While testing with supertest I have noticed that after a test run netstat reports a connection in TIME_WAIT state for every call (get, post, etc.) made with a supertest agent. This can become a problem for me doing frequent and larger test runs - my system actually runs out of either file handles or ports (not sure which.)
My app binds to port 3000 and it's my understanding that if the app is bound to a port supertest won't bind to an ephemeral port.
Here's an abridged version of how my app and test suite are written:
app.js
test.js
For every
await agent.(get|post|put)...
there seems to be a connection on a different port. Is there some way to reduce the number of connections opened in my test suite? Is it possible to reuse a connection, or even just have connections close so they're not stuck in TIME_WAIT taking up resources?Below is a sample output from netstat after a suite that made 11 "agent" calls - ports 6379 and 5432 are connections to redis and postgres respectively, all the rest I think are between supertest and my app: