This is an automated email from the ASF dual-hosted git repository.
erisu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-paramedic.git
The following commit(s) were added to refs/heads/master by this push:
new ae6dc41 feat!: remove custom port & port range support (#289)
ae6dc41 is described below
commit ae6dc415db44a97d71698302fd306c0042829ff3
Author: エリス <[email protected]>
AuthorDate: Thu Dec 18 14:21:24 2025 +0900
feat!: remove custom port & port range support (#289)
* feat!: remove tcp-port-used & refactor server creation
* feat!: remove support for custom ports
---
README.md | 15 +-----
lib/LocalServer.js | 112 +++++++++++++++++++++++++-----------------
lib/ParamedicConfig.js | 11 -----
lib/paramedic.js | 3 +-
main.js | 3 +-
package-lock.json | 64 +-----------------------
package.json | 1 -
paramedic-plugin/paramedic.js | 36 ++------------
8 files changed, 73 insertions(+), 172 deletions(-)
diff --git a/README.md b/README.md
index 6fea4f5..6106c89 100644
--- a/README.md
+++ b/README.md
@@ -53,8 +53,6 @@ Cordova Paramedic is currently used to automatically run all
plugin tests on CI.
- [`--justbuild` (optional)](#--justbuild-optional)
- [Emulator/Device to use for tests](#emulatordevice-to-use-for-tests)
- [`--target` (optional)](#--target-optional)
- - [Test Result Server](#test-result-server)
- - [`--port` (optional)](#--port-optional)
- [Test configuration](#test-configuration)
- [`--timeout` (optional)](#--timeout-optional)
- [`--outputDir` (optional)](#--outputdir-optional)
@@ -239,7 +237,7 @@ cordova-paramedic --platform ios --plugin
cordova-plugin-inappbrowser --justbuil
#### `--target` (optional)
-For Android: The device ID (from `adb devices -l`) of a device the tests
should be run on.
+For Android: The device ID (from `adb devices -l`) of a device the tests
should be run on.
```shell
cordova-paramedic --platform android --plugin cordova-plugin-contacts --target
02e7f7e9215da7f8
@@ -251,17 +249,6 @@ For iOS: A string that is used to pick the device (from
the `cordova run --list
cordova-paramedic --platform ios --plugin cordova-plugin-contacts --target
"iPhone-8"
```
-### Test Result Server
-
-#### `--port` (optional)
-
-Port to use for posting results from emulator back to paramedic server
(default is from `8008`). You can also specify a range using `--startport` and
`endport` and paramedic will select the first available.
-
-```shell
-cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser --port
8010
-cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser
--startport 8000 endport 8020
-```
-
### Test configuration
#### `--timeout` (optional)
diff --git a/lib/LocalServer.js b/lib/LocalServer.js
index 7be4e34..90e5caf 100644
--- a/lib/LocalServer.js
+++ b/lib/LocalServer.js
@@ -21,7 +21,6 @@ const http = require('node:http');
const { EventEmitter } = require('node:events');
const WebSocket = require('ws');
-const portChecker = require('tcp-port-used');
const { logger, utilities } = require('./utils');
@@ -49,16 +48,20 @@ const WS_VALID_EVENTS = [
];
class LocalServer extends EventEmitter {
- constructor (port) {
+ constructor (config, httpServer, port) {
super();
+ this.config = config;
+ this.httpServer = httpServer;
this.port = port;
- this.httpServer = null;
+
this.wss = null;
}
- createSocketListener () {
- this.httpServer = http.createServer();
+ /**
+ * Setup a WebSocket Server with the running HTTP server.
+ */
+ createWebSocketServer () {
this.wss = new WebSocket.Server({ server: this.httpServer });
/**
@@ -132,12 +135,6 @@ class LocalServer extends EventEmitter {
}
}, WS_HEARTBEAT_INTERVAL);
- this.httpServer.listen(this.port, '0.0.0.0', () => {
- logger.info(
- `[paramedic] local-server: WebSocket server listening on
ws://0.0.0.0:${this.port}`
- );
- });
-
this.wss.stop = () => {
clearInterval(interval);
this.httpServer.close();
@@ -153,12 +150,11 @@ class LocalServer extends EventEmitter {
* Android emulators must use their special loopback address 10.0.2.2.
*
* @param {string} platform - Platform name (e.g., "android" or "ios").
- * @param {boolean} shouldReversePort - Whether ADB reverse port is
enabled.
* @returns {string} IP address the host
*/
- getServerIP (platform, shouldReversePort = false) {
+ getServerIP (platform) {
// Android emulator
- if (platform === utilities.ANDROID && !shouldReversePort) {
+ if (platform === utilities.ANDROID) {
return '10.0.2.2';
}
// iOS simulator/devices & Android device with reverse, or desktop
@@ -175,9 +171,46 @@ class LocalServer extends EventEmitter {
return `ws://${this.getServerIP(platform)}:${this.port}`;
}
+ /**
+ * Check if a device is connected by checking the client size.
+ *
+ * @returns {Boolean}
+ */
isDeviceConnected () {
return this.wss && this.wss.clients.size > 0;
}
+
+ /**
+ * Attempts to start a server that the testing app uses to send back test
results.
+ *
+ * @param {ParamedicConfig} config
+ * The paramedic configuration object containing relevant settings
+ * (e.g., port range to try, verbose logging flag, etc).
+ * @returns {Promise<LocalServer>}
+ */
+ static async startServer (config) {
+
logger.warn('------------------------------------------------------------');
+ logger.warn('2. Create and configure local server to receive test
results');
+
logger.warn('------------------------------------------------------------');
+
+ // Holder for the running server instance and used port.
+ logger.normal('[paramedic] Creating local server...');
+ try {
+ const httpServer = await attemptToCreateServer();
+ const port = httpServer.address().port;
+ logger.normal(`[paramedic] Server is running on port: ${port}`);
+
+ // Now create a WebSocket server
+ const localServer = new LocalServer(config, httpServer, port);
+ localServer.createWebSocketServer();
+
+ return localServer;
+ } catch (err) {
+ if (config.isVerbose()) {
+ logger.warn(`[paramedic] Failed to create local server with
error: ${err.message}`);
+ }
+ }
+ }
}
/**
@@ -190,38 +223,25 @@ function toReadableDateTime (epochMs) {
return new Date(epochMs).toLocaleString();
}
-function getRandomInt (min, max) {
- return Math.floor(Math.random() * (max - min)) + min;
+/**
+ * Attempts to create a server and start listening on any random port.
+ *
+ * Failure case:
+ * - The Promise is rejected if the server fails to listen.
+ *
+ * Success case:
+ * - The Promise is resolved with the server instance once it successfully
+ * begins listening.
+ *
+ * @returns Promise<Server|Error>
+ */
+function attemptToCreateServer () {
+ return new Promise((resolve, reject) => {
+ const server = http.createServer();
+ server.on('error', reject);
+ server.on('listening', () => resolve(server));
+ server.listen(0, '0.0.0.0');
+ });
}
-LocalServer.startServer = function (ports, noListener) {
-
logger.warn('------------------------------------------------------------');
- logger.warn('2. Create and configure local server to receive test
results');
-
logger.warn('------------------------------------------------------------');
-
- logger.normal('local-server: scanning ports from ' + ports.start + ' to '
+ ports.end);
-
- return LocalServer.getAvailablePort(ports.start, ports.end)
- .then((port) => {
- logger.normal('local-server: port ' + port + ' is available');
- logger.info('local-server: starting local medic server');
-
- const localServer = new LocalServer(port);
-
- if (!noListener) localServer.createSocketListener();
-
- return localServer;
- });
-};
-
-LocalServer.getAvailablePort = function (startPort, endPort) {
- const port = getRandomInt(startPort, endPort);
- return portChecker.check(port)
- .then((isInUse) => {
- if (!isInUse) return port;
- if (startPort < endPort) return
LocalServer.getAvailablePort(startPort, endPort);
- throw new Error('Unable to find available port');
- });
-};
-
module.exports = LocalServer;
diff --git a/lib/ParamedicConfig.js b/lib/ParamedicConfig.js
index 6363205..18afe9b 100644
--- a/lib/ParamedicConfig.js
+++ b/lib/ParamedicConfig.js
@@ -17,8 +17,6 @@
under the License.
*/
-const DEFAULT_START_PORT = 7008;
-const DEFAULT_END_PORT = 7208;
const DEFAULT_TIMEOUT = 60 * 60 * 1000; // 60 minutes in msec - this will
become a param
const DEFAULT_CLI = 'cordova'; // use globally installed cordova by default
@@ -95,13 +93,6 @@ class ParamedicConfig {
this._config.skipMainTests = skipMainTests;
}
- getPorts () {
- return {
- start: this._config.startPort || DEFAULT_START_PORT,
- end: this._config.endPort || DEFAULT_END_PORT
- };
- }
-
getTimeout () {
return DEFAULT_TIMEOUT;
}
@@ -153,8 +144,6 @@ ParamedicConfig.parseFromArguments = function (argv) {
args: '',
plugins: Array.isArray(argv.plugin) ? argv.plugin : [argv.plugin],
verbose: !!argv.verbose,
- startPort: argv.startport || argv.port,
- endPort: argv.endport || argv.port,
outputDir: argv.outputDir ? argv.outputDir : null,
tccDb: argv.tccDbPath ? argv.tccDb : null,
cleanUpAfterRun: !!argv.cleanUpAfterRun,
diff --git a/lib/paramedic.js b/lib/paramedic.js
index 8a04eb2..fdee09b 100644
--- a/lib/paramedic.js
+++ b/lib/paramedic.js
@@ -73,8 +73,7 @@ class ParamedicRunner {
// Start server if the tests are to run
if (this.config.runMainTests()) {
- const noListener = false;
- this.server = await Server.startServer(this.config.getPorts(),
noListener);
+ this.server = await Server.startServer(this.config);
this.injectReporters();
this.subcribeForEvents();
diff --git a/main.js b/main.js
index af28efd..131acbb 100755
--- a/main.js
+++ b/main.js
@@ -27,7 +27,7 @@ const { utilities } = require('./lib/utils');
const USAGE = `Error missing args.
-cordova-paramedic --platform PLATFORM --plugin PATH [--justbuild --timeout
MSECS --startport PORTNUM --endport PORTNUM --version ...]
+cordova-paramedic --platform PLATFORM --plugin PATH [--justbuild --timeout
MSECS --version ...]
--platform PLATFORM : the platform id. Currently supports 'ios', 'browser'
'android'.
Path to platform can be specified as link to git repo like:
@@ -47,7 +47,6 @@ cordova-paramedic --platform PLATFORM --plugin PATH
[--justbuild --timeout MSECS
--justbuild : (optional) just builds the project, without running the tests
--outputDir : (optional) path to save Junit results file & Device logs
--skipMainTests : (optional) Do not run main (cordova-test-framework) tests
---startport/--endport PORTNUM : (optional) ports to find available and use for
posting results from emulator back to paramedic server (default is from 8008 to
8009)
--target : (optional) target to deploy to
--tccDb : (optional) iOS only - specifies the path for the TCC.db file to be
copied.
--timeout MSECS : (optional) time in millisecs to wait for tests to pass|fail
diff --git a/package-lock.json b/package-lock.json
index dc14a95..9bcaa36 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,7 +13,6 @@
"jasmine-reporters": "^2.5.2",
"jasmine-spec-reporter": "^7.0.0",
"minimist": "^1.2.8",
- "tcp-port-used": "^1.0.2",
"tmp": "^0.2.5",
"tree-kill": "^1.2.2",
"ws": "^8.18.3"
@@ -862,6 +861,7 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity":
"sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/define-data-property": {
@@ -1987,15 +1987,6 @@
"node": ">= 0.4"
}
},
- "node_modules/ip-regex": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
- "integrity":
"sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-array-buffer": {
"version": "3.0.5",
"resolved":
"https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
@@ -2339,12 +2330,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-url": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
- "integrity":
"sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
- "license": "MIT"
- },
"node_modules/is-weakmap": {
"version": "2.0.2",
"resolved":
"https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
@@ -2391,20 +2376,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is2": {
- "version": "2.0.9",
- "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.9.tgz",
- "integrity":
"sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==",
- "license": "MIT",
- "dependencies": {
- "deep-is": "^0.1.3",
- "ip-regex": "^4.1.0",
- "is-url": "^1.2.4"
- },
- "engines": {
- "node": ">=v0.10.0"
- }
- },
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
@@ -3378,39 +3349,6 @@
"url": "https://opencollective.com/webpack"
}
},
- "node_modules/tcp-port-used": {
- "version": "1.0.2",
- "resolved":
"https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
- "integrity":
"sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
- "license": "MIT",
- "dependencies": {
- "debug": "4.3.1",
- "is2": "^2.0.6"
- }
- },
- "node_modules/tcp-port-used/node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity":
"sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/tcp-port-used/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity":
"sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "license": "MIT"
- },
"node_modules/tmp": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
diff --git a/package.json b/package.json
index 7d32d58..e0f3393 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,6 @@
"jasmine-reporters": "^2.5.2",
"jasmine-spec-reporter": "^7.0.0",
"minimist": "^1.2.8",
- "tcp-port-used": "^1.0.2",
"tmp": "^0.2.5",
"tree-kill": "^1.2.2",
"ws": "^8.18.3"
diff --git a/paramedic-plugin/paramedic.js b/paramedic-plugin/paramedic.js
index 8bbc8a7..7333cc6 100644
--- a/paramedic-plugin/paramedic.js
+++ b/paramedic-plugin/paramedic.js
@@ -18,11 +18,7 @@
under the License.
*/
-const PARAMEDIC_SERVER_DEFAULT_URL = 'http://127.0.0.1:8008';
-
-function Paramedic () {
-
-}
+function Paramedic () { }
Paramedic.prototype.initialize = function () {
const me = this;
@@ -108,41 +104,15 @@ Paramedic.prototype.loadParamedicServerUrl = function () {
xhr.open('GET', '../medic.json', false);
xhr.send(null);
const cfg = JSON.parse(xhr.responseText);
-
- return cfg.logurl || PARAMEDIC_SERVER_DEFAULT_URL;
+ return cfg.logurl;
} catch (ex) {
console.log('Unable to load paramedic server url: ' + ex);
}
- return PARAMEDIC_SERVER_DEFAULT_URL;
-};
-
-Paramedic.prototype.loadParamedicServerUrl = function () {
- return getMedicConfig().logurl;
+ throw new Error('[paramedic] Failed to find logurl.');
};
cordova.paramedic = new Paramedic();
cordova.paramedic.initialize();
-function getMedicConfig () {
- const cfg = {
- logurl: PARAMEDIC_SERVER_DEFAULT_URL
- };
-
- try {
- // attempt to synchronously load medic config
- const xhr = new XMLHttpRequest();
- xhr.open('GET', '../medic.json', false);
- xhr.send(null);
- const parsedCfg = JSON.parse(xhr.responseText);
- if (parsedCfg.logurl) {
- cfg.logurl = parsedCfg.logurl;
- }
- } catch (ex) {
- console.log('Unable to load paramedic server url: ' + ex);
- }
-
- return cfg;
-}
-
module.exports = Paramedic;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]