This repository has been archived by the owner on Jul 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(launcher): reorganize launcher
- Loading branch information
Showing
8 changed files
with
352 additions
and
329 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
var child = require('child_process'); | ||
var q = require('q'); | ||
var TaskLogger = require('./TaskLogger.js'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var util = require('util'); | ||
|
||
|
||
/** | ||
* A fork of a runner for running a specified task. The RunnerFork will | ||
* start a new process that calls on '/runFromLauncher.js'. | ||
* | ||
* @constructor | ||
* @param {object} task Task to run. | ||
*/ | ||
var RunnerFork = function(configFile, additionalConfig, task, runInFork) { | ||
this.configFile = configFile; | ||
this.additionalConfig = additionalConfig; | ||
this.task = task; | ||
this.runInFork = runInFork; | ||
}; | ||
util.inherits(RunnerFork, EventEmitter); | ||
|
||
/** | ||
* Sends the run command. | ||
*/ | ||
RunnerFork.prototype.run = function() { | ||
var self = this; | ||
|
||
var runResults = { | ||
taskId: this.task.taskId, | ||
specs: this.task.specs, | ||
capabilities: this.task.capabilities, | ||
// The following are populated while running the test: | ||
failedCount: 0, | ||
exitCode: -1, | ||
specResults: [] | ||
} | ||
|
||
if (this.runInFork) { | ||
var deferred = q.defer(); | ||
|
||
var childProcess = child.fork( | ||
__dirname + '/runFromLauncher.js', | ||
process.argv.slice(2), { | ||
cwd: process.cwd(), | ||
silent: true | ||
} | ||
); | ||
var taskLogger = new TaskLogger(this.task, childProcess.pid); | ||
|
||
// stdout pipe | ||
childProcess.stdout.on('data', function(data) { | ||
taskLogger.log(data); | ||
}); | ||
|
||
// stderr pipe | ||
childProcess.stderr.on('data', function(data) { | ||
taskLogger.log(data); | ||
}); | ||
|
||
childProcess.on('message', function(m) { | ||
switch (m.event) { | ||
case 'testPass': | ||
process.stdout.write('.'); | ||
break; | ||
case 'testFail': | ||
process.stdout.write('F'); | ||
break; | ||
case 'testsDone': | ||
runResults.failedCount = m.results.failedCount; | ||
runResults.specResults = m.results.specResults; | ||
break; | ||
} | ||
}) | ||
.on('error', function(err) { | ||
taskLogger.flush(); | ||
deferred.reject(err); | ||
}) | ||
.on('exit', function(code) { | ||
taskLogger.flush(); | ||
runResults.exitCode = code; | ||
deferred.resolve(runResults); | ||
}); | ||
|
||
childProcess.send({ | ||
command: 'run', | ||
configFile: this.configFile, | ||
additionalConfig: this.additionalConfig, | ||
capabilities: this.task.capabilities, | ||
specs: this.task.specs | ||
}); | ||
|
||
return deferred.promise; | ||
} else { | ||
var ConfigParser = require('./configParser'); | ||
var configParser = new ConfigParser(); | ||
if (this.configFile) { | ||
configParser.addFileConfig(this.configFile); | ||
} | ||
if (this.additionalConfig) { | ||
configParser.addConfig(this.additionalConfig); | ||
} | ||
var config = configParser.getConfig(); | ||
config.capabilities = this.task.capabilities; | ||
config.specs = this.task.specs; | ||
|
||
var Runner = require('./runner'); | ||
var runner = new Runner(config); | ||
|
||
runner.on('testsDone', function(results) { | ||
runResults.failedCount = results.failedCount; | ||
runResults.specResults = results.specResults; | ||
}) | ||
|
||
return runner.run().then(function(exitCode) { | ||
runResults.exitCode = exitCode; | ||
return runResults; | ||
}); | ||
} | ||
}; | ||
|
||
module.exports = RunnerFork; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
var EOL = require('os').EOL; | ||
|
||
/** | ||
* Log output such that metadata are appended. | ||
* Calling log(data) will not flush to console until you call flush() | ||
* | ||
* @constructor | ||
* @param {object} task Task that is being reported. | ||
* @param {number} pid PID of process running the task. | ||
*/ | ||
var TaskLogger = function(task, pid) { | ||
this.task = task; | ||
this.pid = pid; | ||
this.buffer = ''; | ||
this.insertTag = true; | ||
|
||
this.logHeader_(); | ||
}; | ||
|
||
/** | ||
* Report the header for the current task including information such as | ||
* PID, browser name/version, task Id, specs being run. | ||
* | ||
* @private | ||
*/ | ||
TaskLogger.prototype.logHeader_ = function() { | ||
var output = 'PID: ' + this.pid + EOL; | ||
if (this.task.specs.length === 1) { | ||
output += 'Specs: '+ this.task.specs.toString() + EOL + EOL; | ||
} | ||
this.log(output); | ||
}; | ||
|
||
|
||
/** | ||
* Flushes the buffer to stdout. | ||
*/ | ||
TaskLogger.prototype.flush = function() { | ||
if (this.buffer) { | ||
// Flush buffer if nonempty | ||
process.stdout.write(EOL + '------------------------------------' + EOL); | ||
process.stdout.write(this.buffer); | ||
process.stdout.write(EOL); | ||
this.buffer = ''; | ||
} | ||
}; | ||
|
||
/** | ||
* Log the data in the argument. The data will be saved to a buffer | ||
* until flush() is called. | ||
* | ||
* @param {string} data | ||
*/ | ||
TaskLogger.prototype.log = function(data) { | ||
var tag = '['; | ||
var capabilities = this.task.capabilities; | ||
tag += (capabilities.browserName) ? | ||
capabilities.browserName : ''; | ||
tag += (capabilities.version) ? | ||
(' ' + capabilities.version) : ''; | ||
tag += (capabilities.platform) ? | ||
(' ' + capabilities.platform) : ''; | ||
tag += (' #' + this.task.taskId); | ||
tag += '] '; | ||
|
||
data = data.toString(); | ||
for ( var i = 0; i < data.length; i++ ) { | ||
if (this.insertTag) { | ||
this.insertTag = false; | ||
// This ensures that the '\x1B[0m' appears before the tag, so that | ||
// data remains correct when color is not processed. | ||
// See https://github.com/angular/protractor/pull/1216 | ||
if (data[i] === '\x1B' && data.substring(i, i+4) === '\x1B[0m' ) { | ||
this.buffer += ('\x1B[0m' + tag); | ||
i += 3; | ||
continue; | ||
} | ||
|
||
this.buffer += tag; | ||
} | ||
if (data[i] === '\n') { | ||
this.insertTag = true; | ||
} | ||
this.buffer += data[i]; | ||
} | ||
}; | ||
|
||
module.exports = TaskLogger; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.