diff --git a/.travis.yml b/.travis.yml index 1aa2d8b..1693c3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,3 @@ node_js: - v5 - v4 sudo: false -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/package.json b/package.json index 47e55f2..bfb3d7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "testarmada-magellan", - "version": "10.0.4", + "version": "10.0.5", "description": "Massively parallel automated testing", "main": "src/main", "directories": { diff --git a/src/test_runner.js b/src/test_runner.js index 5e02171..5823d88 100644 --- a/src/test_runner.js +++ b/src/test_runner.js @@ -544,7 +544,8 @@ class TestRunner { msg.push("-->"); msg.push((this.serial ? "Serial mode" : "Worker " + worker.index) + ","); - msg.push("mock port:" + worker.portOffset + ","); + msg.push("port range: [" + worker.portOffset + ", " + + (worker.portOffset + settings.BASE_PORT_SPACING - 1) + "],"); if (worker.token) { msg.push("VM token:" + worker.token + ","); @@ -567,7 +568,26 @@ class TestRunner { this.mkdirSync(tempAssetPath); - testRun = new TestRunClass({ + // magellan default port rule + let ports = { + seleniumPort: worker.portOffset, + mockingPort: null + }; + + if (settings.BASE_PORT_SPACING > 1) { + ports.mockingPort = worker.portOffset + 1; + } + + // if executor has its own port rule + if (test.executor.getPorts + && typeof test.executor.getPorts === "function") { + ports = test.executor.getPorts({ + portOffset: worker.portOffset, + portIndent: settings.BASE_PORT_SPACING + }); + } + + testRun = new TestRunClass(_.assign({ guid: childBuildId, // The id of this build, used by some reporters to identify the overall suite run. This @@ -588,11 +608,8 @@ class TestRunner { // executor: this.executors[test.profile.executor], // The locator object originally generated by the plugin itself - locator: test.locator, - - seleniumPort: worker.portOffset + 1, - mockingPort: worker.portOffset - }); + locator: test.locator + }, ports)); } catch (e) { deferred.reject(e); } diff --git a/src/worker_allocator.js b/src/worker_allocator.js index ab71d6c..20d9cc0 100644 --- a/src/worker_allocator.js +++ b/src/worker_allocator.js @@ -20,11 +20,15 @@ class Allocator { debug: settings.debug }, opts); - if (this.debug) { - logger.log("Worker Allocator starting."); - logger.log("Port allocation range from: " + settings.BASE_PORT_START + " to " - + (settings.BASE_PORT_START + settings.BASE_PORT_RANGE - 1) + " with " - + settings.BASE_PORT_SPACING + " ports available to each worker."); + logger.debug("Worker Allocator starting."); + logger.debug("Port allocation range from: " + settings.BASE_PORT_START + " to " + + (settings.BASE_PORT_START + settings.BASE_PORT_RANGE - 1) + " with " + + settings.BASE_PORT_SPACING + " ports available to each worker."); + + /* istanbul ignore if */ + if (settings.BASE_PORT_SPACING === 1) { + logger.warn("Only one port is available per worker"); + logger.warn("Increase --base_port_spacing to allocate more ports per worker if needed"); } this.initializeWorkers(MAX_WORKERS); @@ -82,11 +86,13 @@ class Allocator { const portOffset = this.getNextPort(); - // Standard Magellan convention: port = mock, port + 1 = selenium - // Other ports after this within the BASE_PORT_SPACING range can - // be used for whatever the user desires, so those are labelled - // as "generic" (if found to be occupied, that is). - const desiredPortLabels = ["mocking port", "selenium port"]; + // Standard Magellan port convention: + // let n = settings.BASE_PORT_SPACING - 1; + // portOffset : selenium server + // portOffset + 1 : pre-assigned for mocking (available for application to use) + // ... + // portOffset + n : available for application to use + const desiredPortLabels = ["selenium port"]; const desiredPorts = []; // if BASE_PORT_SPACING is the default of 3, we'll check 3 ports diff --git a/test/base_listener.js b/test/base_listener.js index c4a5ab4..76a42f7 100644 --- a/test/base_listener.js +++ b/test/base_listener.js @@ -8,7 +8,7 @@ const expect = chai.expect; chai.use(chaiAsPromised); describe("listener", () => { - + it("should act like a class", () => { expect(new BaseListener()).to.be.an.instanceof(BaseListener); }); diff --git a/test/cli_help.js b/test/cli_help.js index fe1e056..c2095e6 100644 --- a/test/cli_help.js +++ b/test/cli_help.js @@ -25,9 +25,27 @@ const opts = { "category": "Usability", "visible": false, "description": "FAKE_INVISIBLE_DES" + }, + "another-visible-command": { + "category": "Usability", + "description": "FAKE_ANOTHER_VISIBLE_DES" } } } + }, + framework: "FAKE_FRAME_NAME", + testFramework: { + help: { + tags: { + example: "tag1,tag2", + visible: true, + description: "Run all tests that match a list of comma-delimited tags (eg: tag1,tag2)" + }, + group: { + example: "prefix/path", + description: "Run all tests that match a path prefix like ./tests/smoke" + } + } } } }; diff --git a/test/test_runner.js b/test/test_runner.js index 994c211..05fc51f 100644 --- a/test/test_runner.js +++ b/test/test_runner.js @@ -37,6 +37,12 @@ const executors = { name: "testarmada-magellan-sauce-executor", shortName: "sauce", + getPorts(opts) { + return { + seleniumPort: opts.portOffset, + mockingPort: opts.portOffset + 1 + } + }, getProfiles(opts) { return new Promise((resolve) => { resolve(opts.profiles);