Skip to content

Commit ba9c6f5

Browse files
authored
Merge pull request #266 from pact-foundation/fix/port-check-49
fix(port-check): make port check more resilient. Fixes #49
2 parents 8baf35f + ee0aa71 commit ba9c6f5

3 files changed

Lines changed: 28 additions & 21 deletions

File tree

src/common/net.spec.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const expect = chai.expect;
88
chai.use(chaiAsPromised);
99

1010
describe("Net", () => {
11-
const port = 1234;
11+
const port = 4567;
1212
const host = "0.0.0.0";
1313
const specialPort = process.platform.match("win") ? -1 : 80;
1414

@@ -21,22 +21,14 @@ describe("Net", () => {
2121

2222
context("when the port is available", () => {
2323
it("should return a fulfilled promise", () => {
24-
expect(isPortAvailable(port, host)).to.eventually.be.fulfilled;
24+
expect(isPortAvailable(port + 1, host)).to.eventually.be.fulfilled;
2525
});
2626
});
2727

2828
context("when the port is unavailable", () => {
29-
it("should return a rejected promise", done => {
30-
createServer(port).then((server: { close(): any }) => {
31-
isPortAvailable(port, host).then(
32-
() => {
33-
server.close();
34-
done(new Error(`Port ${port} should not be available`));
35-
},
36-
(e: any) => {
37-
done();
38-
}
39-
);
29+
it("should return a rejected promise", () => {
30+
createServer(port).then((_: { close(): any }) => {
31+
expect(isPortAvailable(port, host)).to.eventually.be.rejected;
4032
});
4133
});
4234
});

src/common/net.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,31 @@
55
*/
66

77
import * as net from "net";
8+
import { Promise as bluebird } from "bluebird";
89

9-
const isPortAvailable = (port: number, host: string): Promise<void> => {
10+
const isPortAvailable = (port: number, host: string): Promise<void> =>
11+
Promise.resolve(bluebird.each([host, "127.0.0.1", "localhost", "0.0.0.0"], h =>
12+
portCheck(port, h)
13+
)
14+
.then(() => Promise.resolve(undefined))
15+
.catch(e => Promise.reject(e)));
16+
17+
const portCheck = (port: number, host: string): Promise<void> => {
1018
return new Promise((resolve, reject) => {
11-
const server: any = net.createServer()
19+
const server: any = net
20+
.createServer()
1221
.listen({ port, host, exclusive: true })
13-
.on("error", (e: any) => (e.code === "EADDRINUSE" ? reject(new Error(`Port ${port} is unavailable`)) : reject(e)))
14-
.on("listening", () => server.once("close", () => resolve()).close());
22+
.on("error", (e: any) => {
23+
if (e.code === "EADDRINUSE") {
24+
reject(new Error(`Port ${port} is unavailable`))
25+
} else {
26+
reject(e);
27+
}
28+
})
29+
.on("listening", () => {
30+
server.once("close", () => resolve()).close();
31+
});
1532
});
1633
};
1734

18-
export {
19-
isPortAvailable,
20-
};
35+
export { isPortAvailable, portCheck };

src/pact.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class Pact {
9292
public setup(): Promise<void> {
9393
return isPortAvailable(this.opts.port, this.opts.host)
9494
// Need to wrap it this way until we remove q.Promise from pact-node
95-
.then(() => new Promise<void>((resolve, reject) => this.server.start().then(() => resolve(), () => reject())));
95+
.then(() => new Promise<void>((resolve, reject) => this.server.start().then(() => resolve(), (e: any) => reject(e))))
9696
}
9797

9898
/**

0 commit comments

Comments
 (0)