Skip to content

Commit

Permalink
fix(port-check): make port check more resilient. Fixes #49
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed Feb 9, 2019
1 parent 8baf35f commit ee0aa71
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 21 deletions.
18 changes: 5 additions & 13 deletions src/common/net.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const expect = chai.expect;
chai.use(chaiAsPromised);

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

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

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

context("when the port is unavailable", () => {
it("should return a rejected promise", done => {
createServer(port).then((server: { close(): any }) => {
isPortAvailable(port, host).then(
() => {
server.close();
done(new Error(`Port ${port} should not be available`));
},
(e: any) => {
done();
}
);
it("should return a rejected promise", () => {
createServer(port).then((_: { close(): any }) => {
expect(isPortAvailable(port, host)).to.eventually.be.rejected;
});
});
});
Expand Down
29 changes: 22 additions & 7 deletions src/common/net.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,31 @@
*/

import * as net from "net";
import { Promise as bluebird } from "bluebird";

const isPortAvailable = (port: number, host: string): Promise<void> => {
const isPortAvailable = (port: number, host: string): Promise<void> =>
Promise.resolve(bluebird.each([host, "127.0.0.1", "localhost", "0.0.0.0"], h =>
portCheck(port, h)
)
.then(() => Promise.resolve(undefined))
.catch(e => Promise.reject(e)));

const portCheck = (port: number, host: string): Promise<void> => {
return new Promise((resolve, reject) => {
const server: any = net.createServer()
const server: any = net
.createServer()
.listen({ port, host, exclusive: true })
.on("error", (e: any) => (e.code === "EADDRINUSE" ? reject(new Error(`Port ${port} is unavailable`)) : reject(e)))
.on("listening", () => server.once("close", () => resolve()).close());
.on("error", (e: any) => {
if (e.code === "EADDRINUSE") {
reject(new Error(`Port ${port} is unavailable`))
} else {
reject(e);
}
})
.on("listening", () => {
server.once("close", () => resolve()).close();
});
});
};

export {
isPortAvailable,
};
export { isPortAvailable, portCheck };
2 changes: 1 addition & 1 deletion src/pact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class Pact {
public setup(): Promise<void> {
return isPortAvailable(this.opts.port, this.opts.host)
// Need to wrap it this way until we remove q.Promise from pact-node
.then(() => new Promise<void>((resolve, reject) => this.server.start().then(() => resolve(), () => reject())));
.then(() => new Promise<void>((resolve, reject) => this.server.start().then(() => resolve(), (e: any) => reject(e))))
}

/**
Expand Down

0 comments on commit ee0aa71

Please sign in to comment.