Skip to content

Commit bc57514

Browse files
authoredJun 7, 2019
fix: retry finding port when port is null and get ports in sequence (#1993)
1 parent 2029211 commit bc57514

File tree

5 files changed

+103
-14
lines changed

5 files changed

+103
-14
lines changed
 

Diff for: ‎lib/utils/findPort.js

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
'use strict';
22

3-
const { getPortPromise } = require('portfinder');
3+
const pRetry = require('p-retry');
4+
const portfinder = require('portfinder');
45
const defaultPort = require('./defaultPort');
56
const defaultTo = require('./defaultTo');
67
const tryParseInt = require('./tryParseInt');
78

9+
function runPortFinder() {
10+
return new Promise((resolve, reject) => {
11+
portfinder.basePort = defaultPort;
12+
portfinder.getPort((error, port) => {
13+
if (error) {
14+
return reject(error);
15+
}
16+
17+
return resolve(port);
18+
});
19+
});
20+
}
21+
822
function findPort(port) {
9-
if (typeof port !== 'undefined') {
23+
if (port) {
1024
return Promise.resolve(port);
1125
}
1226

@@ -19,10 +33,7 @@ function findPort(port) {
1933
3
2034
);
2135

22-
return getPortPromise({
23-
port: defaultPort,
24-
stopPort: defaultPort + defaultPortRetry,
25-
});
36+
return pRetry(runPortFinder, { retries: defaultPortRetry });
2637
}
2738

2839
module.exports = findPort;

Diff for: ‎package-lock.json

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: ‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"killable": "^1.0.1",
5252
"loglevel": "^1.6.2",
5353
"opn": "^5.5.0",
54+
"p-retry": "^3.0.1",
5455
"portfinder": "^1.0.20",
5556
"schema-utils": "^1.0.0",
5657
"selfsigned": "^1.10.4",
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`findPort util should throws the error when the port isn't found 1`] = `"No open ports found in between 8080 and 8085"`;
3+
exports[`findPort util should throws the error when the port isn't found 1`] = `"busy"`;

Diff for: ‎test/server/utils/findPort.test.js

+71-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const http = require('http');
4+
const portfinder = require('portfinder');
45
const findPort = require('../../../lib/utils/findPort');
56

67
describe('findPort util', () => {
@@ -23,7 +24,7 @@ describe('findPort util', () => {
2324
});
2425

2526
function createDummyServers(n) {
26-
return [...new Array(n)].reduce((p, _, i) => {
27+
return (Array.isArray(n) ? n : [...new Array(n)]).reduce((p, _, i) => {
2728
return p.then(() => {
2829
return new Promise((resolve) => {
2930
const server = http.createServer();
@@ -42,25 +43,88 @@ describe('findPort util', () => {
4243
});
4344
});
4445

45-
it('should retry finding the port for up to defaultPortRetry times', () => {
46-
const retryCount = 5;
46+
it.only('should returns the port when the port is null', () => {
47+
const retryCount = 2;
48+
49+
process.env.DEFAULT_PORT_RETRY = 2;
50+
51+
return createDummyServers(retryCount)
52+
.then(() => findPort(null))
53+
.then((port) => {
54+
expect(port).toEqual(8080 + retryCount);
55+
});
56+
});
57+
58+
it('should returns the port when the port is undefined', () => {
59+
const retryCount = 2;
60+
61+
process.env.DEFAULT_PORT_RETRY = 2;
62+
63+
return (
64+
createDummyServers(retryCount)
65+
// eslint-disable-next-line no-undefined
66+
.then(() => findPort(undefined))
67+
.then((port) => {
68+
expect(port).toEqual(8080 + retryCount);
69+
})
70+
);
71+
});
72+
73+
it('should retry finding the port for up to defaultPortRetry times (number)', () => {
74+
const retryCount = 3;
4775

4876
process.env.DEFAULT_PORT_RETRY = retryCount;
4977

5078
return createDummyServers(retryCount)
51-
.then(findPort)
79+
.then(() => findPort())
5280
.then((port) => {
5381
expect(port).toEqual(8080 + retryCount);
5482
});
5583
});
5684

85+
it('should retry finding the port for up to defaultPortRetry times (string)', () => {
86+
const retryCount = 3;
87+
88+
process.env.DEFAULT_PORT_RETRY = `${retryCount}`;
89+
90+
return createDummyServers(retryCount)
91+
.then(() => findPort())
92+
.then((port) => {
93+
expect(port).toEqual(8080 + retryCount);
94+
});
95+
});
96+
97+
it('should retry finding the port when serial ports are busy', () => {
98+
const busyPorts = [8080, 8081, 8082, 8083];
99+
100+
process.env.DEFAULT_PORT_RETRY = 3;
101+
102+
return createDummyServers(busyPorts)
103+
.then(() => findPort())
104+
.then((port) => {
105+
expect(port).toEqual(8080 + busyPorts.length);
106+
});
107+
});
108+
57109
it("should throws the error when the port isn't found", () => {
58-
process.env.DEFAULT_PORT_RETRY = 5;
110+
expect.assertions(1);
111+
112+
const spy = jest
113+
.spyOn(portfinder, 'getPort')
114+
.mockImplementation((callback) => {
115+
return callback(new Error('busy'));
116+
});
59117

60-
return createDummyServers(10)
61-
.then(findPort)
118+
const retryCount = 1;
119+
120+
process.env.DEFAULT_PORT_RETRY = 0;
121+
122+
return createDummyServers(retryCount)
123+
.then(() => findPort())
62124
.catch((err) => {
63125
expect(err.message).toMatchSnapshot();
126+
127+
spy.mockRestore();
64128
});
65129
});
66130
});

0 commit comments

Comments
 (0)
Please sign in to comment.