Closed mk-pmb closed 8 years ago
From the failing Travis log:
test/express.js ....................................... [31m0/1[0m[31m 830ms[0m
express
[31mnot ok Error: listen EADDRINUSE[0m
I'll just re-commit and hope the next test run has better luck with the random numbers. This might be more interesting:
test/express-error.js ................................. [32m3/3[0m
connections property is deprecated. Use getConnections() method
Environment proxy config? what?
The environment variables http_proxy
, https_proxy
, ftp_proxy
and similar. Sometimes they are used in all-uppercase, could be a windows variation.
It's a traditional feature of some network programs and libs, including the request package: "Controlling proxy behaviour using environment variables".
Interesting.
Is it possible to set these while running tests? Say, NO_PROXY='*' npm test
? That might be a better solution, especially if someone did want to apply proxy settings for God knows what reason.
The express test is probably easy to fix by doing a search in the test file for connection
and naively changing it to getConnections()
. That'd be my guess.
I think a good solution would be to refactor a lot of these patterns into a test helper module (maybe setup-loopback-listen
):
That pre-configured instance of request could bypass env proxy settings:
Furthermore, the proxy configuration option can be explicitly set to false / null to opt out of proxying altogether for that request.
I'm not eager to refactor all those tests myself, so anyone interested please jump in if @jfhbrook approves of the idea.
Since I can't find a mention of OS-assigned ports in the http
module docs (only in net
), here's how it works on my Ubuntu. Notice that it binds to localhost, where current tests seem to bind to 0.0.0.0
/::
(any adapter).
var srv = require('http').createServer();
srv.listen(0, 'localhost', function serverReady(err) {
var addr = srv.address(),
baseUrl = 'http://' + addr.address + ':' + addr.port + '/';
console.log(baseUrl); // http://127.0.0.1:43482/
srv.close();
});
Now back to your questions:
Is it possible to set these while running tests?
It is. The post above shows a more elegant way than using process.env
. However, even that one only lasts "while running tests":
$ export DUMMY=hi; echo a $DUMMY; nodejs -e '
> console.log(1, process.env.DUMMY);
> delete process.env.DUMMY;
> console.log(2, process.env.DUMMY);
> '; echo b $DUMMY
a hi
1 'hi'
2 undefined
b hi
Say, NO_PROXY='*' npm test?
That should work as well. I used http_proxy= npm test
to verify my suspicion. You could even modify package.json
to:
"test": "env http_proxy= https_proxy= tap test/*.js"
… but that would kill any chance to set a custom proxy.
That might be a better solution, especially if someone did want to apply proxy settings for God knows what reason.
Then tests should at least warn that proxy settings are in effect. If the tests default to using system proxy settings, they should be liberal in what they accept from that proxy. Giving some thousand lines of terminal output complaining about transport headers isn't what I had expected from "running the tests before I start tinkering, just to be sure." ;-)
If the proxy settings should be test-specific, the request approach seems fit. For someone who wants to test a special proxy, we should allow them to specify one explicitly for the ecstatic tests, to have a conscious decision about the interception and the potential for test failures. We could use an environment variable ecstatic_proxy
that would be parsed by the setup-loopback-listen
helper.
I'll patch my PR to allow a custom ecstatic_proxy
.
@jekrb did some tests for setting the port via an environment variable in
process-env-port.js, using child_process.spawn
. You could easily use the same approach to test proxy environment variables per test.
About the 0.0.0.0 pattern, I think it's a unix misconception about localhost. Unfortunately ecstatic
support this by outputting that pattern every time you start ecstatic
from the terminal. Basically, 127.0.0.1 = localhost and 0.0.0.0 = any address (which unix translate to localhost because listening to 0.0.0.0 doesn't make sense). On Windows listening to 0.0.0.0 will fail. I guess different flavors of linux have different take on this, but Ubuntu should follow the unix approach.
In case there should ever be a security flaw in ecstatic or the file system it uses for its tests, there may be effective differences between listening on "localhost" or "any address". However, for tests of external listening, here's my example code adapted:
var srv = require('http').createServer();
srv.listen(0, '', function serverReady(err) {
var addr = srv.address(), host = String(addr.address), baseUrl;
if (host.match(/^[0\.:]+$/)) { host = 'localhost'; }
// ^-- e.g. "0.0.0.0", "::", "::0"
baseUrl = 'http://' + host + ':' + addr.port + '/';
console.log(baseUrl); // http://localhost:48592/
srv.close();
});
refactor a lot of these patterns into a test helper module
Yeah, that seems reasonable. I'll turn this into an issue.
"test": "env http_proxy= https_proxy= tap test/*.js"
This would seem like the way to go, except I don't think I can support both windows and nix with that.
I think the best approach here is to document the issue in CONTRIBUTING.md. I'm not sure how to reproduce the behavior you were seeing, so I'll leave that up to you.
I'm going to close this PR for now, not because HTTP_PROXY isn't an issue, but because I don't think this is the right PR to merge. I'll make a separate issue for this, and link in this thread.
The trick that made those tests pass on my test computer.