diff --git a/.gitignore b/.gitignore index a02cca6..24a6997 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ checkstyle.xml tests.tap .travis.yml appveyor.yml +.nyc_output +sandbox diff --git a/.jshintignore b/.jshintignore index 3c3629e..1fd04da 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1 +1,3 @@ node_modules +coverage +.nyc_output diff --git a/.travis.yml b/.travis.yml index 9c72688..1184aad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,11 @@ language: node_js node_js: - - "6" - - "5" - - "4" - - "0.12" - - "0.10" +- '6' +- '5' +- '4' +- '0.12' +- '0.10' +env: + global: + - COVERALLS_PARALLEL=true + - secure: rxAxzXc6ff4UQIMYD46SZQP37fIDdZ2IlMtPx34dp61sIQj9dKAYmjtwr4J7Ra+qiisdia+szvfNLaPa6ThCWj6OOhdwNMd/vRsoGQGHHYMf2qU+uMwA+8TP9WzjLlEVtu3TiU+gNb8YEfMW6TzTRKSHGwC1aNYOa14PhhAygYY= diff --git a/appveyor.yml b/appveyor.yml index 6f844dd..3ee2682 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,6 @@ environment: + COVERALLS_REPO_TOKEN: + secure: sxoCWFzAUW5WrH5KKKY38kZo1oB3Bu+WWJDshymilkDq/rKR4j9qXmrf6Ae/ekt8 matrix: - nodejs_version: '6' - nodejs_version: '5' @@ -7,15 +9,19 @@ environment: - nodejs_version: '0.10' install: - ps: Install-Product node $env:nodejs_version - - set CI=true - npm -g install npm@latest - set PATH=%APPDATA%\npm;%PATH% - npm install matrix: fast_finish: true +branches: + only: + - master build: off version: '{build}' shallow_clone: true -clone_depth: 1 +clone_depth: 10 test_script: - - npm test -- -Rclassic --no-coverage --timeout=3600 + - set CI=true + - set COVERALLS_PARALLEL=true + - npm test -- --reporter=tap diff --git a/demo/.env b/demo/.env index f5ca76c..4531709 100644 --- a/demo/.env +++ b/demo/.env @@ -1,5 +1,5 @@ { - "port": 80, + "port": 8000, "bind": "0.0.0.0", "mysql":{ "host":"localhost", diff --git a/forward.js b/forward.js index f912c46..80f4a99 100644 --- a/forward.js +++ b/forward.js @@ -57,7 +57,9 @@ function startForward(proxy_port, proxy_host) { res.end(); }); - httpServer.listen(proxy_port); + httpServer.listen(proxy_port, '127.0.0.1', function() { + process.send({http: this.address().port}); + }); } startForward(process.env.PROXY_PORT, process.env.PROXY_HOST); diff --git a/lib/forward.js b/lib/forward.js index ae8dabd..9eeafa7 100644 --- a/lib/forward.js +++ b/lib/forward.js @@ -20,9 +20,25 @@ function startForward(port, hostname, emitter) { } else { cons.Alert('Intercepting ALL requests through forward proxy'); } + proc.on('message', function(msg) { + if ('http' in msg) { + port = msg.http; + cons.Alert('Forward Proxy Listening On Port %d', port); + emitter.emit('http', msg.http); + } + }); emitter.once('killall', function(signal) { - cons.Done('Killing Forward Proxy Server on Port %d',port); - proc.kill(signal); + cons.Done('Killing Forward Proxy Server on Port %d', port); + try { + proc.kill(signal); + } catch(_e) { + cons.Warn('Proxy server already dead'); + } + }); + + proc.on('exit', function(code, signal) { + emitter.emit('exit', code, signal); + emitter.emit('killall', 'SIGINT'); }); } diff --git a/lib/proc.js b/lib/proc.js index df75713..fb6938a 100644 --- a/lib/proc.js +++ b/lib/proc.js @@ -51,7 +51,11 @@ function run(key, proc, emitter) { }); emitter.on('killall', function(signal) { - child.kill(signal); + try { + child.kill(signal); + } catch(_e) { + cons.Warn('Proxy server already dead'); + } }); } diff --git a/lib/procfile.js b/lib/procfile.js index 552677b..6dfaf6e 100644 --- a/lib/procfile.js +++ b/lib/procfile.js @@ -12,20 +12,21 @@ function procs(procdata){ var processes = {}; - procdata.toString().split(/\n/).forEach(function(line) { + procdata.toString().split(/\n/).forEach(function(line, lineNo) { if(!line || line[0] === '#') { return; } + lineNo += 1; - var tuple = /^([A-Za-z0-9_-]+):\s*(.+)$/m.exec(line); + var tuple = /^([^:]*):(.*)$/m.exec(line); - var prockey = tuple[1].trim(); - var command = tuple[2].trim(); + var prockey = tuple && tuple[1].trim(); + var command = tuple && tuple[2].trim(); if(!prockey) { - throw new Error('Syntax Error in Procfile, Line %d: No Prockey Found'); + throw new Error('Syntax Error in Procfile, Line ' + lineNo + ': No Prockey Found'); } if(!command) { - throw new Error('Syntax Error in Procfile, Line %d: No Command Found'); + throw new Error('Syntax Error in Procfile, Line ' + lineNo + ': No Command Found'); } processes[prockey] = command; diff --git a/lib/proxy.js b/lib/proxy.js index cccbae8..c76c3d9 100644 --- a/lib/proxy.js +++ b/lib/proxy.js @@ -27,7 +27,7 @@ function f(key, j, ports, proc, reqs, portargs, localhost, emitter, ssl) { } var upstream_size = reqs[key]; - var upstream_port = parseInt(portargs) + j * 100; + var upstream_port = portargs[j]; var proxy = prog.fork(require.resolve('../proxy'), [], { env: { @@ -50,27 +50,31 @@ function f(key, j, ports, proc, reqs, portargs, localhost, emitter, ssl) { port_targets = util.format('(%d-%d)', upstream_port, upstream_port + upstream_size - 1); } - cons.Alert('Starting Proxy Server [%s] %s -> %s', key, port, port_targets); - if (ssl.cert && ssl.key) { - cons.Alert('Starting Secure Proxy Server [%s] %s -> %s', key, ssl_port, port_targets); - } - proxy.on('message', function(msg) { if ('http' in msg) { + port = ports[j] = msg.http; + cons.Alert('Started Proxy Server [%s] %s -> %s', key, port, port_targets); emitter.emit('http', msg.http); } if ('https' in msg) { + port = ports[j] = msg.https; + cons.Alert('Started Secure Proxy Server [%s] %s -> %s', key, port, port_targets); emitter.emit('https', msg.https); } }); emitter.once('killall', function(signal) { cons.Done('Killing Proxy Server on Port %s', port); - proxy.kill(signal); + try { + proxy.kill(signal); + } catch(_e) { + cons.Warn('Proxy server already dead'); + } }); proxy.on('exit', function(code, signal) { - emitter.emit('killall', signal); + emitter.emit('exit', code, signal); + emitter.emit('killall', 'SIGINT'); }); } @@ -80,6 +84,18 @@ function startProxies(reqs, proc, command, emitter, portargs) { if ('proxy' in command) { var localhost = 'localhost'; + if (typeof portargs === 'string') { + portargs = portargs.split(','); + } else if (typeof portargs === 'number') { + portargs = [portargs]; + } + Object.keys(reqs).forEach(function(k, j) { + if (portargs[j]) { + portargs[j] = parseInt(portargs[j]); + } else { + portargs[j] = parseInt(portargs[0]) + j * 100; + } + }); var ports = command.proxy.split(','); diff --git a/lib/smf/foreman-APP.xml b/lib/smf/foreman-APP.xml index 0ecd6c6..1cf3990 100644 --- a/lib/smf/foreman-APP.xml +++ b/lib/smf/foreman-APP.xml @@ -55,4 +55,4 @@ - \ No newline at end of file + diff --git a/package.json b/package.json index e2f68d3..0941c1a 100644 --- a/package.json +++ b/package.json @@ -23,13 +23,13 @@ ], "scripts": { "pretest": "jshint .", - "test": "tap test/*.test.*" + "test": "tap --coverage test/*.test.*" }, "dependencies": { - "commander": "~2.9.0", - "http-proxy": "~1.11.1", + "commander": "^2.9.0", + "http-proxy": "^1.13.2", "mustache": "^2.2.1", - "shell-quote": "~1.4.2" + "shell-quote": "^1.6.0" }, "repository": { "type": "git", @@ -44,9 +44,8 @@ }, "preferGlobal": true, "devDependencies": { - "chai": "~1.9.1", "jshint": "^2.6.3", - "rimraf": "~2.2.8", - "tap": "^0.7.1" + "rimraf": "^2.5.2", + "tap": "^5.7.1" } } diff --git a/test/common.sh b/test/common.sh new file mode 100644 index 0000000..6e78968 --- /dev/null +++ b/test/common.sh @@ -0,0 +1,128 @@ +#!/bin/bash +fails=0 +tests=0 +skips=0 + +trap assert_report EXIT + +function fail() { + local report=$1 + local output=$2 + fails=$((fails+1)) + tests=$((tests+1)) + echo "not ok $tests # $report" >&3 + echo "# $report" >&2 + echo "$output" >&2 +} + +function ok() { + cmd=$1 + tests=$((tests+1)) + echo "ok $tests # $cmd" >&3 +} + +function skip() { + comment=$1 + tests=$((tests+1)) + echo "ok $tests # SKIP $comment" >&3 +} + +function comment() { + echo "# $*" >&3 +} + +function assert_exit() { + expected="$1" + case $expected in + ''|*[!0-9]*) + expected=0 + cmd="$*" + ;; + *) + shift + cmd="$*" + ;; + esac + output=`$cmd 2>&1` + result=$? + report="exit $result should be $expected: '$cmd'" + if test $result -ne $expected; then + fail "$report" "$output" + else + ok "$report" + fi +} + +function assert_file() { + local fname=$1 + if test $# -gt 1; then + shift + found=$(grep -F -e "$*" $fname) + result=$? + if test $result -eq 0; then + ok "needle: '$*' in $fname" + else + fail "needle: '$*' NOT in $fname" + fi + else + report="file exists: $fname" + if test -f $fname; then + ok "$report" + else + fail "$report" + fi + fi +} + +function assert_not_file() { + local fname=$1 + if test $# -gt 1; then + shift + found=$(grep -F -e "$*" $fname) + result=$? + if test $result -eq 0; then + fail "needle: '$*' in $fname" + else + ok "needle: '$*' NOT in $fname" + fi + else + report="file exists: $fname" + if test -f $fname; then + fail "$report" + else + ok "$report" + fi + fi +} + +function bailout() { + fail "$1" + echo "Bail out! $1" >&1 + echo "Bail out! $1" >&2 + echo "Bail out! $1" >&3 + # exit 1 + assert_report +} + +function assert_report() { + if test -z $reported; then + echo "1..$tests" >&3 + reported=1 + fi + exit $fails +} + +echo 'TAP version 13' + +# make fd 3 the new fd 1 and redirect original fd 1 to fd 2 +# this allows us to completely isolate the TAP output from these helpers +# to their own stream +if test -z "$DEBUG"; then + exec 3>&1 2>/dev/null 1>&2 + comment "suppressing stderr, set DEBUG to restore" +else + exec 3>&1 1>&2 +fi + +comment "using npm registry $(npm config get registry)" +comment "using $(basename $(node -p process.execPath))-$(node -p process.version)" diff --git a/test/console-output.test.js b/test/console-output.test.js index 2ce9f46..5d732bf 100644 --- a/test/console-output.test.js +++ b/test/console-output.test.js @@ -3,9 +3,9 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('chai').assert; var util = require('util'); var Console = require('../lib/console'); +var tap = require('tap'); var logs = { log: [], warn: [], error: [] }; var logger = { @@ -14,40 +14,44 @@ var logger = { error: makeLogger(logs.error) }; -var c = new Console(logger); -resetLogs(); +tap.test('log methods', function(t) { + var c = new Console(logger); + resetLogs(); -assert.equal(logs.log.length, 0); -assert.equal(logs.warn.length, 0); -assert.equal(logs.error.length, 0); + t.equal(logs.log.length, 0); + t.equal(logs.warn.length, 0); + t.equal(logs.error.length, 0); -resetLogs(); -c.Alert('ze message'); -assertLogged('log', /\[OKAY\]/); -assertLogged('log', /ze message/); + resetLogs(); + c.Alert('ze message'); + assertLogged(t, 'log', /\[OKAY\]/); + assertLogged(t, 'log', /ze message/); -resetLogs(); -c.Done('ze message'); -assertLogged('log', /\[DONE\]/); -assertLogged('log', /ze message/); + resetLogs(); + c.Done('ze message'); + assertLogged(t, 'log', /\[DONE\]/); + assertLogged(t, 'log', /ze message/); -resetLogs(); -c.Warn('ze warning'); -assertLogged('warn', /\[WARN\]/); -assertLogged('warn', /ze warning/); + resetLogs(); + c.Warn('ze warning'); + assertLogged(t, 'warn', /\[WARN\]/); + assertLogged(t, 'warn', /ze warning/); -resetLogs(); -c.Error('such an error'); -assertLogged('error', /\[FAIL\]/); -assertLogged('error', /such an error/); + resetLogs(); + c.Error('such an error'); + assertLogged(t, 'error', /\[FAIL\]/); + assertLogged(t, 'error', /such an error/); -resetLogs(); -c.raw = true; -c.log('a key', null, 'a log message'); -assertLogged('log', /^a log message$/); -c.raw = false; + resetLogs(); + c.raw = true; + c.log('a key', null, 'a log message'); + assertLogged(t, 'log', /^a log message$/); + c.raw = false; -assert.lengthOf(c.trim('a very long string this is!', 5), 6); + t.equal(c.trim('a very long string this is!', 5).length, 6); + + t.end(); +}); function makeLogger(collector) { return function() { @@ -61,12 +65,12 @@ function resetLogs() { logs.error.splice(0, logs.error.length); } -function assertLogged(logName, pattern) { +function assertLogged(t, logName, pattern) { var actual = logs[logName][logs[logName].length - 1]; Object.keys(logs).forEach(function (log) { - assert.lengthOf(logs[log], logName === log ? 1 : 0); + t.equal(logs[log].length, logName === log ? 1 : 0); }); - assert.match(actual, pattern); + t.match(actual, pattern); } diff --git a/test/console-trim.test.js b/test/console-trim.test.js index 191973d..48bfc46 100644 --- a/test/console-trim.test.js +++ b/test/console-trim.test.js @@ -6,9 +6,9 @@ // Needed before requiring colors, otherwise its colorizers are no-ops. process.stdout.isTTY = true; -var assert = require('chai').assert; var Console = require('../lib/console').Console; var colors = require('../lib/colors'); +var tap = require('tap'); var red = colors.red('red'); var blue = colors.blue('blue'); @@ -16,17 +16,20 @@ var blue = colors.blue('blue'); var long = 'Roses are red, Violets are blue, this string is long, and should be trimmed, too!'; var colorLong = long.replace('red', red).replace('blue', blue); -assert.lengthOf(long, 81); -assert.lengthOf(colorLong, 99); -assert.equal(Console.trim(colorLong, 50), Console.trim(long, 50)); +tap.test(function(t) { + t.equal(long.length, 81); + t.equal(colorLong.length, 99); + t.equal(Console.trim(colorLong, 50), Console.trim(long, 50)); -assert.equal(Console.trim(colorLong, long.length), colorLong, - 'trim() should leave colors intact if no trimming is performed'); + t.equal(Console.trim(colorLong, long.length), colorLong, + 'trim() should leave colors intact if no trimming is performed'); -var indented = ' indented'; -assert.equal(Console.trim(indented, 100), indented, - 'trim() should always preserve leading whitespace'); -var padded = ' padded '; -var trimmed = ' padded'; -assert.equal(Console.trim(padded, 100), trimmed, - 'trim() should always trim trailing whitespace'); + var indented = ' indented'; + t.equal(Console.trim(indented, 100), indented, + 'trim() should always preserve leading whitespace'); + var padded = ' padded '; + var trimmed = ' padded'; + t.equal(Console.trim(padded, 100), trimmed, + 'trim() should always trim trailing whitespace'); + t.end(); +}); diff --git a/test/envs-commented.test.js b/test/envs-commented.test.js index 7257a07..9617920 100644 --- a/test/envs-commented.test.js +++ b/test/envs-commented.test.js @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var envs = require('../lib/envs'); var input = '### This is a config file...\n' + @@ -22,5 +22,6 @@ var loadedEnv = envs.keyValue(input); var dumpedEnv = envs.dumpEnv(loadedEnv); var loadedFlat = envs.keyValue(expected); var dumpedFlat = envs.dumpEnv(loadedFlat); -assert.equal(dumpedEnv, expected); -assert.equal(dumpedFlat, expected); + +tap.equal(dumpedEnv, expected); +tap.equal(dumpedFlat, expected); diff --git a/test/envs-empty.test.js b/test/envs-empty.test.js index 61a302a..aed57bb 100644 --- a/test/envs-empty.test.js +++ b/test/envs-empty.test.js @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var envs = require('../lib/envs'); var emptyEnvs = ['', '\n', ' \n \n \n']; @@ -11,7 +11,7 @@ var emptyEnvs = ['', '\n', ' \n \n \n']; emptyEnvs.forEach(function (env) { var loaded = envs.keyValue(env); // {} == {} - assert.equal(Object.keys(loaded).length, 0); + tap.equal(Object.keys(loaded).length, 0); }); -assert.equal(envs.dumpEnv({}), '\n'); +tap.equal(envs.dumpEnv({}), '\n'); diff --git a/test/envs-json.test.js b/test/envs-json.test.js index b6ba462..746e0ed 100644 --- a/test/envs-json.test.js +++ b/test/envs-json.test.js @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var envs = require('../lib/envs'); var json = { @@ -31,5 +31,5 @@ var dumped = [ 'TOP_OTHER_2=two', ].join('\n') + '\n'; -assert.deepEqual(envs.flattenJSON(json), flattened); -assert.equal(envs.dumpEnv(flattened), dumped); +tap.deepEqual(envs.flattenJSON(json), flattened); +tap.equal(envs.dumpEnv(flattened), dumped); diff --git a/test/envs-quoted.test.js b/test/envs-quoted.test.js index 865e1cb..20b71ee 100644 --- a/test/envs-quoted.test.js +++ b/test/envs-quoted.test.js @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var envs = require('../lib/envs'); var parsedHash = envs.keyValue( @@ -13,6 +13,6 @@ var parsedHash = envs.keyValue( 'key3 = base64=== \n' ); -assert.equal(parsedHash.key, 'quoted#hash'); -assert.equal(parsedHash.key2, 'stripped'); -assert.equal(parsedHash.key3, 'base64==='); +tap.equal(parsedHash.key, 'quoted#hash'); +tap.equal(parsedHash.key2, 'stripped'); +tap.equal(parsedHash.key3, 'base64==='); diff --git a/test/export-custom-absolute.test.sh b/test/export-custom-absolute.test.sh deleted file mode 100755 index 0705404..0000000 --- a/test/export-custom-absolute.test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -PATH=$(dirname $(which node)) $NF export \ - --app upstart-test --user test-user \ - --out sandbox --type upstart \ - --template $(pwd)/fixtures/upstart-custom-templates \ - --env fixtures/env.env --procfile fixtures/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -# Fixtures can be updated to match output by running `npm test --update-fixtures` -test -n "$npm_config_update_fixtures" && cp sandbox/* fixtures/upstart-custom/ - -diff -r -u fixtures/upstart-custom sandbox 1>&2 || exit $? diff --git a/test/export-custom-relative.test.sh b/test/export-custom-relative.test.sh deleted file mode 100755 index 963e109..0000000 --- a/test/export-custom-relative.test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -PATH=$(dirname $(which node)) $NF export \ - --app upstart-test --user test-user \ - --out sandbox --type upstart \ - --template fixtures/upstart-custom-templates \ - --env fixtures/env.env --procfile fixtures/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -# Fixtures can be updated to match output by running `npm test --update-fixtures` -test -n "$npm_config_update_fixtures" && cp sandbox/* fixtures/upstart-custom/ - -diff -r -u fixtures/upstart-custom sandbox 1>&2 || exit $? diff --git a/test/export-path-default.test.sh b/test/export-path-default.test.sh deleted file mode 100755 index 3e5bd4d..0000000 --- a/test/export-path-default.test.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" - -rm -rf sandbox -mkdir -p sandbox - -echo "PATH=something-totally-bogus" > sandbox/.env -echo "web: node app.js" > sandbox/Procfile - -node ../nf.js export --out sandbox --type upstart-single \ - --env sandbox/.env --procfile sandbox/Procfile - -grep 'env PATH="something-totally-bogus"' sandbox/foreman-web.conf || exit $? diff --git a/test/export-supervisord.test.sh b/test/export-supervisord.test.sh deleted file mode 100755 index d875013..0000000 --- a/test/export-supervisord.test.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -PATH=$(dirname $(which node)) $NF export \ - --app supervisord-test --user test-user \ - --out sandbox --type supervisord \ - --env fixtures/env.env --procfile fixtures/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -diff -r -u fixtures/supervisord sandbox 1>&2 || exit $? diff --git a/test/export-systemd.test.sh b/test/export-systemd.test.sh deleted file mode 100755 index b6531a4..0000000 --- a/test/export-systemd.test.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -PATH=$(dirname $(which node)) $NF export \ - --app systemd-test --user test-user \ - --out sandbox --type systemd \ - --env fixtures/env.env --procfile fixtures/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -diff -r -u fixtures/systemd sandbox 1>&2 || exit $? diff --git a/test/export-upstart-single.test.sh b/test/export-upstart-single.test.sh deleted file mode 100755 index 9e3461b..0000000 --- a/test/export-upstart-single.test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -PATH=$(dirname $(which node)) $NF export \ - --app upstart-single-test --user test-user \ - --out sandbox --type upstart-single \ - --env fixtures/env.env --procfile fixtures/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -# Fixtures can be updated to match output by running `npm test --update-fixtures` -test -n "$npm_config_update_fixtures" && cp sandbox/* fixtures/upstart-single/ - -diff -r -u fixtures/upstart-single sandbox 1>&2 || exit $? diff --git a/test/export-upstart.test.sh b/test/export-upstart.test.sh deleted file mode 100755 index cdf89bd..0000000 --- a/test/export-upstart.test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -PATH=$(dirname $(which node)) $NF export \ - --app upstart-test --user test-user \ - --out sandbox --type upstart \ - --cwd '/EXPORT/PATH' \ - --env fixtures/env.env --procfile fixtures/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -# Fixtures can be updated to match output by running `npm test --update-fixtures` -test -n "$npm_config_update_fixtures" && cp sandbox/* fixtures/upstart/ - -diff -r -u fixtures/upstart sandbox 1>&2 || exit $? diff --git a/test/exporters.test.sh b/test/exporters.test.sh new file mode 100755 index 0000000..32fdcb1 --- /dev/null +++ b/test/exporters.test.sh @@ -0,0 +1,69 @@ +#!/bin/bash +DIR=$(dirname "${BASH_SOURCE[0]}") +source $DIR/common.sh + +NODE=node +NF="$DIR/../nf.js" +SED=`which gsed || which sed` + +comment $(env | grep NYC) + +assert_sandbox_contents() { + fixture=$1 + + $SED -i '' -e "s%/EXPORT/PATH%TEST_DIR%g" \ + -e "s%$(pwd)%TEST_DIR%g" \ + $DIR/sandbox/* + + # Fixtures can be updated to match output by running `npm test --update-fixtures` + if test -n "$npm_config_update_fixtures"; then + mkdir -p $DIR/fixtures/$fixture + cp $DIR/sandbox/* $DIR/fixtures/$fixture/ + fi + + assert_exit diff -r -u $DIR/fixtures/$fixture $DIR/sandbox +} + +test_exporter() { + type=$1 + fixture=$2 + args=$3 + rm -rf $DIR/sandbox + mkdir -p $DIR/sandbox + assert_exit $NODE $NF export \ + --app $type-test --user test-user \ + --out $DIR/sandbox --type $type \ + $args \ + --cwd '/EXPORT/PATH' \ + --env $DIR/fixtures/env.env --procfile $DIR/fixtures/Procfile + assert_sandbox_contents $fixture +} + +test_exporter "upstart" "upstart" +test_exporter "upstart-single" "upstart-single" +comment "custom template path, relative" +test_exporter "upstart" "upstart-custom" "--template test/fixtures/upstart-custom-templates" +comment "custom template path, absolute" +test_exporter "upstart" "upstart-custom" "--template $DIR/fixtures/upstart-custom-templates" +test_exporter "systemd" "systemd" +test_exporter "supervisord" "supervisord" +test_exporter "smf" "smf" + +comment "trivial configs" +rm -rf $DIR/sandbox +mkdir -p $DIR/sandbox +echo "PATH=something-totally-bogus" > $DIR/sandbox/.env +echo "web: node app.js" > $DIR/sandbox/Procfile +assert_exit $NODE $NF export \ + --out $DIR/sandbox --type upstart-single \ + --env $DIR/sandbox/.env --procfile $DIR/sandbox/Procfile +assert_file $DIR/sandbox/foreman-web.conf 'env PATH="something-totally-bogus"' + +comment "comments in Procfile" +rm -rf $DIR/sandbox +mkdir -p $DIR/sandbox +assert_exit $NODE $NF export \ + --out $DIR/sandbox --type upstart-single \ + --env $DIR/fixtures/procfile-comment.env \ + --procfile $DIR/fixtures/procfile-comment.Procfile +assert_sandbox_contents procfile-comment diff --git a/test/fixtures/env.env b/test/fixtures/env.env index b041a65..66b96b4 100644 --- a/test/fixtures/env.env +++ b/test/fixtures/env.env @@ -3,3 +3,4 @@ bind=0.0.0.0 mysql_host=localhost mysql_user=toast mysql_pass=peanutbutter +PATH=TEST_PATH diff --git a/test/fixtures/nocmd.Procfile b/test/fixtures/nocmd.Procfile new file mode 100644 index 0000000..f5bd21c --- /dev/null +++ b/test/fixtures/nocmd.Procfile @@ -0,0 +1,2 @@ +nocmd1: +nocmd2: diff --git a/test/fixtures/nokey.Procfile b/test/fixtures/nokey.Procfile new file mode 100644 index 0000000..9cba381 --- /dev/null +++ b/test/fixtures/nokey.Procfile @@ -0,0 +1,2 @@ +: nokey +: nameless command diff --git a/test/fixtures/procfile-comment/Procfile b/test/fixtures/procfile-comment.Procfile similarity index 100% rename from test/fixtures/procfile-comment/Procfile rename to test/fixtures/procfile-comment.Procfile diff --git a/test/fixtures/procfile-comment/.env b/test/fixtures/procfile-comment.env similarity index 100% rename from test/fixtures/procfile-comment/.env rename to test/fixtures/procfile-comment.env diff --git a/test/fixtures/smf/smf-test-api.xml b/test/fixtures/smf/smf-test-api.xml new file mode 100644 index 0000000..9af11dd --- /dev/null +++ b/test/fixtures/smf/smf-test-api.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/fixtures/smf/smf-test-log.xml b/test/fixtures/smf/smf-test-log.xml new file mode 100644 index 0000000..5626980 --- /dev/null +++ b/test/fixtures/smf/smf-test-log.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/fixtures/smf/smf-test-web.xml b/test/fixtures/smf/smf-test-web.xml new file mode 100644 index 0000000..1e56097 --- /dev/null +++ b/test/fixtures/smf/smf-test-web.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/fixtures/systemd/systemd-test-api-1.service b/test/fixtures/systemd/systemd-test-api-1.service index 3302321..c6e46b6 100644 --- a/test/fixtures/systemd/systemd-test-api-1.service +++ b/test/fixtures/systemd/systemd-test-api-1.service @@ -10,7 +10,7 @@ WorkingDirectory=TEST_DIR User=test-user Group=test-user -EnvironmentFile=-TEST_DIR/fixtures/env.env +EnvironmentFile=-TEST_DIR/test/fixtures/env.env Environment=PORT=5100 StandardInput=null diff --git a/test/fixtures/systemd/systemd-test-log-1.service b/test/fixtures/systemd/systemd-test-log-1.service index a1e1f15..f885fb8 100644 --- a/test/fixtures/systemd/systemd-test-log-1.service +++ b/test/fixtures/systemd/systemd-test-log-1.service @@ -10,7 +10,7 @@ WorkingDirectory=TEST_DIR User=test-user Group=test-user -EnvironmentFile=-TEST_DIR/fixtures/env.env +EnvironmentFile=-TEST_DIR/test/fixtures/env.env Environment=PORT=5200 StandardInput=null diff --git a/test/fixtures/systemd/systemd-test-web-1.service b/test/fixtures/systemd/systemd-test-web-1.service index f3f6ca1..cf72509 100644 --- a/test/fixtures/systemd/systemd-test-web-1.service +++ b/test/fixtures/systemd/systemd-test-web-1.service @@ -10,7 +10,7 @@ WorkingDirectory=TEST_DIR User=test-user Group=test-user -EnvironmentFile=-TEST_DIR/fixtures/env.env +EnvironmentFile=-TEST_DIR/test/fixtures/env.env Environment=PORT=5000 StandardInput=null diff --git a/test/fixtures/upstart/upstart-test-api-1.conf b/test/fixtures/upstart/upstart-test-api-1.conf index 3492daf..a05b4f9 100644 --- a/test/fixtures/upstart/upstart-test-api-1.conf +++ b/test/fixtures/upstart/upstart-test-api-1.conf @@ -13,7 +13,7 @@ env PORT="5100" env FOREMAN_WORKER_NAME="api.1" -chdir /EXPORT/PATH +chdir TEST_DIR setuid test-user setgid test-user diff --git a/test/fixtures/upstart/upstart-test-log-1.conf b/test/fixtures/upstart/upstart-test-log-1.conf index 69c3032..4d1b315 100644 --- a/test/fixtures/upstart/upstart-test-log-1.conf +++ b/test/fixtures/upstart/upstart-test-log-1.conf @@ -13,7 +13,7 @@ env PORT="5200" env FOREMAN_WORKER_NAME="log.1" -chdir /EXPORT/PATH +chdir TEST_DIR setuid test-user setgid test-user diff --git a/test/fixtures/upstart/upstart-test-web-1.conf b/test/fixtures/upstart/upstart-test-web-1.conf index a9fdac7..4fd3eba 100644 --- a/test/fixtures/upstart/upstart-test-web-1.conf +++ b/test/fixtures/upstart/upstart-test-web-1.conf @@ -13,7 +13,7 @@ env PORT="5000" env FOREMAN_WORKER_NAME="web.1" -chdir /EXPORT/PATH +chdir TEST_DIR setuid test-user setgid test-user diff --git a/test/forward-proxy.test.js b/test/forward-proxy.test.js new file mode 100644 index 0000000..fb4363d --- /dev/null +++ b/test/forward-proxy.test.js @@ -0,0 +1,106 @@ +var tap = require('tap'); +var events = require('events'); +var http = require('http'); + +var Console = require('../lib/console'); +Console.Console = new Console({ + log: tap.comment, + warn: tap.comment, + error: tap.comment, +}); + +var startServer = require('./server').startServer; +var startProxy = require('../lib/forward').startForward; + +var emitter = new events.EventEmitter(); + +var proxy_port = 0; +var server_port = 0; +var server = null; + +tap.test('start server', function(t) { + server = startServer(0, emitter).on('listening', function() { + t.comment('test server listening:', this.address()); + t.assert(this.address()); + server_port = this.address().port; + t.end(); + }); +}); + +tap.test('start proxy', function(t) { + emitter.once('http', function(port) { + t.comment('test proxy listening:', port); + t.assert(port, 'listening'); + + proxy_port = port; + t.end(); + }); + startProxy(0, 'foreman.com', emitter); +}); + + +tap.test('test proxies', function(t) { + t.plan(2*2); + http.get({ + port: proxy_port, + path: 'http://foreman.com:' + server_port + '/', + }, verify); + t.comment('ensuring proxy handles missing path'); + http.get({ + port: proxy_port, + path: 'http://foreman.com:' + server_port, + }, verify); + function verify(response) { + t.equal(response.statusCode, 200); + + var body = ''; + response.setEncoding('utf8'); + response.on('data', function (chunk) { + body += chunk; + }); + response.on('end', function () { + body = JSON.parse(body); + t.match(body, { + server: { + port: server_port, + }, + request: { + headers: { + host: 'localhost:' + proxy_port, + } + } + }); + }); + } +}); + +tap.test('test proxy failure', function(t) { + server.close(); + http.get({ + port: proxy_port, + path: 'http://foreman.com:' + server_port + '/', + }, verify); + function verify(response) { + t.equal(response.statusCode, 500); + + var body = ''; + response.setEncoding('utf8'); + response.on('data', function (chunk) { + body += chunk; + }); + response.on('end', function () { + t.match(body, /Upstream Proxy Error/i); + t.end(); + }); + } +}); + +tap.test('cleanup', function(t) { + emitter.emit('killall', 'SIGINT'); + emitter.on('exit', function(code, signal) { + // to ensure process lives long enough to finish logging + setTimeout(function noop(){}, 200); + t.pass('forward proxy exited'); + t.end(); + }); +}); diff --git a/test/procfile-comment.test.sh b/test/procfile-comment.test.sh deleted file mode 100755 index 6670421..0000000 --- a/test/procfile-comment.test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -NF="node ../nf.js" -SED=`which gsed || which sed` - -rm -rf sandbox -mkdir -p sandbox - -echo "PATH=something-totally-bogus" > sandbox/.env -printf "#norun: touch should-not-exist.js\nrun: touch should-exist.js\n# norun: touch should-not-exist-2.js\n" > sandbox/Procfile - -node ../nf.js export --out sandbox --env sandbox/.env --type upstart-single --procfile sandbox/Procfile - -$SED -i '' -e "s%$(pwd)%TEST_DIR%g" \ - -e "s%$(dirname $(which node))%TEST_PATH%g" sandbox/* - -# Fixtures can be updated to match output by running `npm test --update-fixtures` -test -n "$npm_config_update_fixtures" && cp sandbox/* fixtures/procfile-comment/ - -diff -r -u fixtures/procfile-comment sandbox 1>&2 || exit $? diff --git a/test/proxy-multi.test.js b/test/proxy-multi.test.js new file mode 100644 index 0000000..b47bcda --- /dev/null +++ b/test/proxy-multi.test.js @@ -0,0 +1,96 @@ +// Copyright IBM Corp. 2016. All Rights Reserved. +// Node module: foreman +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +var tap = require('tap'); +var events = require('events'); +var http = require('http'); + +var Console = require('../lib/console'); +Console.Console = new Console({ + log: tap.comment, + warn: tap.comment, + error: tap.comment, +}); + +var startServer = require('./server').startServer; +var startProxies = require('../lib/proxy').startProxies; +var servers = []; + +var emitter = new events.EventEmitter(); + +var proxy_port = []; +var server_port = []; + +var reqs = { + 'test-web': 1, + 'test-api': 1, +}; +var proc = { + 'test-web': '', + 'test-api': '' +}; +var command = { + proxy: '0,0', +}; + +tap.test('start server 1', function(t) { + servers[0] = startServer(0, emitter).on('listening', function() { + t.comment('test server listening:', this.address()); + t.assert(this.address()); + server_port[0] = this.address().port; + t.end(); + }); +}); + +tap.test('start server 2', function(t) { + servers[1] = startServer(0, emitter).on('listening', function() { + t.comment('test server listening:', this.address()); + t.assert(this.address()); + server_port[1] = this.address().port; + t.end(); + }); +}); + +tap.test('start proxies', function(t) { + t.plan(2); + emitter.on('http', function(port) { + proxy_port.push(port); + t.assert(port, 'listening: ' + port); + t.comment('proxy ports: ', proxy_port); + }); + startProxies(reqs, proc, command, emitter, server_port); +}); + +tap.test('test proxies', function(t) { + t.plan(2*2); + t.comment('testing proxy on port ' + proxy_port[0]); + http.get({ port: proxy_port[0] }, verifyResponse).on('error', t.ifErr); + t.comment('testing proxy on port ' + proxy_port[1]); + http.get({ port: proxy_port[1] }, verifyResponse).on('error', t.ifErr); + function verifyResponse(response) { + t.equal(response.statusCode, 200); + var body = ''; + response.setEncoding('utf8'); + response.on('data', function (chunk) { + body += chunk; + }); + response.on('end', function () { + body = JSON.parse(body); + t.equal(body.request.headers['x-forwarded-proto'], 'http'); + }); + } +}); + +tap.test('cleanup', function(t) { + t.plan(4); + servers[0].close(t.ifErr); + servers[1].close(t.ifErr); + emitter.on('exit', function(code, signal) { + // to ensure process lives long enough to finish logging + setTimeout(function noop(){}, 200); + t.ok(code || signal); + }); + emitter.emit('killall', 'SIGINT'); +}); diff --git a/test/proxy-ssl.test.js b/test/proxy-ssl.test.js index e276fe1..252832e 100644 --- a/test/proxy-ssl.test.js +++ b/test/proxy-ssl.test.js @@ -3,16 +3,26 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var events = require('events'); var https = require('https'); +var path = require('path'); + +var Console = require('../lib/console'); +Console.Console = new Console({ + log: tap.comment, + warn: tap.comment, + error: tap.comment, +}); var startServer = require('./server').startServer; var startProxies = require('../lib/proxy').startProxies; +var server = null; var emitter = new events.EventEmitter(); var proxy_port = 0; +var server_port = 0; var reqs = { 'test-web': 1 @@ -22,25 +32,34 @@ var proc = { }; var command = { proxy: proxy_port.toString(), - sslCert: './fixtures/certs/my-server.crt.pem', - sslKey: './fixtures/certs/my-server.key.pem' + sslCert: path.resolve(__dirname, 'fixtures', 'certs', 'my-server.crt.pem'), + sslKey: path.resolve(__dirname, 'fixtures', 'certs', 'my-server.key.pem'), }; -startServer(0, emitter).on('listening', function() { - console.error('test server listening:', this.address()); - startProxies(reqs, proc, command, emitter, this.address().port); +tap.test('start server', function(t) { + server = startServer(0, emitter).on('listening', function() { + t.comment('test server listening:', this.address()); + t.assert(this.address()); + server_port = this.address().port; + t.end(); + }); +}); + +tap.test('start proxies', function(t) { emitter.once('https', function(port) { + t.assert(port, 'listening'); proxy_port = port; - test_proxy(); + t.end(); }); + startProxies(reqs, proc, command, emitter, server_port); }); -function test_proxy() { +tap.test('test proxies', function(t) { https.get({ port: proxy_port, rejectUnauthorized: false }, function (response) { - assert.equal(response.statusCode, 200); + t.equal(response.statusCode, 200); var body = ''; response.setEncoding('utf8'); @@ -49,10 +68,19 @@ function test_proxy() { }); response.on('end', function () { body = JSON.parse(body); - assert.equal(body.request.headers['x-forwarded-proto'], 'https'); - - // Only after the response has been returned can we shut down properly - emitter.emit('killall', 'SIGINT'); + t.equal(body.request.headers['x-forwarded-proto'], 'https'); + t.end(); }); }); -} +}); + +tap.test('cleanup', function(t) { + t.plan(2); + server.close(t.ifErr); + emitter.emit('killall', 'SIGINT'); + emitter.on('exit', function(code, signal) { + // to ensure process lives long enough to finish logging + setTimeout(function noop(){}, 200); + t.pass('proxy exitted'); + }); +}); diff --git a/test/proxy.test.js b/test/proxy.test.js index e43aeb9..444031d 100644 --- a/test/proxy.test.js +++ b/test/proxy.test.js @@ -3,16 +3,25 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var events = require('events'); var http = require('http'); +var Console = require('../lib/console'); +Console.Console = new Console({ + log: tap.comment, + warn: tap.comment, + error: tap.comment, +}); + var startServer = require('./server').startServer; var startProxies = require('../lib/proxy').startProxies; var emitter = new events.EventEmitter(); +var server = null; var proxy_port = 0; +var server_port = 0; var reqs = { 'test-web': 1 @@ -24,20 +33,29 @@ var command = { proxy: proxy_port.toString() }; -startServer(0, emitter).on('listening', function() { - console.error('test server listening:', this.address()); - startProxies(reqs, proc, command, emitter, this.address().port); +tap.test('start server', function(t) { + server = startServer(0, emitter).on('listening', function() { + t.comment('test server listening:', this.address()); + t.assert(this.address()); + server_port = this.address().port; + t.end(); + }); +}); + +tap.test('start proxies', function(t) { emitter.once('http', function(port) { + t.assert(port, 'listening'); proxy_port = port; - test_proxy(); + t.end(); }); + startProxies(reqs, proc, command, emitter, server_port); }); -function test_proxy() { +tap.test('test proxies', function(t) { http.get({ port: proxy_port }, function (response) { - assert.equal(response.statusCode, 200); + t.equal(response.statusCode, 200); var body = ''; response.setEncoding('utf8'); @@ -46,10 +64,40 @@ function test_proxy() { }); response.on('end', function () { body = JSON.parse(body); - assert.equal(body.request.headers['x-forwarded-proto'], 'http'); + t.equal(body.request.headers['x-forwarded-proto'], 'http'); + + t.end(); + }); + }); +}); + +tap.test('test proxy failure', function(t) { + server.close(); + http.get({ + port: proxy_port, + path: 'http://foreman.com:' + server_port + '/', + }, verify); + function verify(response) { + t.equal(response.statusCode, 500); - // Only after the response has been returned can we shut down properly - emitter.emit('killall', 'SIGINT'); + var body = ''; + response.setEncoding('utf8'); + response.on('data', function (chunk) { + body += chunk; }); + response.on('end', function () { + t.match(body, /Upstream Proxy Error/i); + t.end(); + }); + } +}); + +tap.test('cleanup', function(t) { + emitter.on('exit', function(code, signal) { + // to ensure process lives long enough to finish logging + setTimeout(function noop(){}, 200); + t.pass('proxy exitted'); + t.end(); }); -} + emitter.emit('killall', 'SIGINT'); +}); diff --git a/test/reqs.test.js b/test/reqs.test.js new file mode 100644 index 0000000..bc6fd63 --- /dev/null +++ b/test/reqs.test.js @@ -0,0 +1,40 @@ +var tap = require('tap'); +var requirements = require('../lib/requirements'); + +tap.test('parsing', function(t) { + t.test('empty', function(t) { + var args = []; + var procs = {}; + var reqs = requirements.getreqs(args, procs); + t.deepEqual(reqs, {}); + t.end(); + }); + t.test('simple', function(t) { + var args = ['web=1,api=2,log=1']; + var procs = {web: 'node web', api: 'node api', log: 'node log'}; + var reqs = requirements.getreqs(args, procs); + t.deepEqual(reqs, {web: 1, api: 2, log: 1}); + t.end(); + }); + t.end(); +}); + +tap.test('padding', function(t) { + t.test('empty', function(t) { + var reqs = {}; + var padding = requirements.calculatePadding(reqs); + t.equal(padding, 12); + t.end(); + }); + t.test('empty', function(t) { + var reqs = { + web: 1, + api: 2, + log: 1, + }; + var padding = requirements.calculatePadding(reqs); + t.equal(padding, 16); + t.end(); + }); + t.end(); +}); diff --git a/test/run-once.test.js b/test/run-once.test.js index 75fddd3..bfc8b87 100644 --- a/test/run-once.test.js +++ b/test/run-once.test.js @@ -3,39 +3,50 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -var assert = require('assert'); +var tap = require('tap'); var rimraf = require('rimraf'); var fs = require('fs'); var once = require('../lib/proc').once; +var path = require('path'); var envs = { FILENAME: "should-also-exist.txt" }; -var callbackCounter = 0; -var callbackIncrementer = function(code){ - if(code === 0) { - callbackCounter++; - } -}; -rimraf.sync('./sandbox'); -fs.mkdirSync('./sandbox'); -process.chdir('./sandbox'); +var SANDBOX = path.resolve(__dirname, 'sandbox'); +rimraf.sync(SANDBOX); +fs.mkdirSync(SANDBOX); +process.chdir(SANDBOX); -assert.equal(fs.existsSync('./should-exist.txt'), false); -assert.equal(fs.existsSync('./should-also-exist.txt'), false); -assert.equal(fs.existsSync('./should-not-exist.txt'), false); +tap.test('preconditions', function(t) { + t.equal(fs.existsSync('./should-exist.txt'), false); + t.equal(fs.existsSync('./should-also-exist.txt'), false); + t.equal(fs.existsSync('./should-not-exist.txt'), false); + t.end(); +}); + +tap.test('literal', function(t) { + once("touch should-exist.txt", null, function(code) { + t.equal(code, 0); + t.end(); + }); +}); -once("touch should-exist.txt", null, callbackIncrementer); -// TODO: this is currently OS dependent, but we should probably do the -// expansion ourselves -if (process.platform === 'win32') { - once("touch %FILENAME%", envs, callbackIncrementer); -} else { - once("touch $FILENAME", envs, callbackIncrementer); -} +tap.test('expansion', function(t) { + // TODO: this is currently OS dependent, but we should probably do the + // expansion ourselves + if (process.platform === 'win32') { + once("touch %FILENAME%", envs, exitsCleanly); + } else { + once("touch $FILENAME", envs, exitsCleanly); + } + function exitsCleanly(code) { + t.equal(code, 0); + t.end(); + } +}); -process.on('exit', function() { - assert.equal(callbackCounter, 2); - assert.equal(fs.existsSync('./should-exist.txt'), true); - assert.equal(fs.existsSync('./should-not-exist.txt'), false); - assert.equal(fs.existsSync(envs.FILENAME), true, 'should exist: ' + envs.FILENAME); +tap.test('verification', function(t) { + t.equal(fs.existsSync('./should-exist.txt'), true); + t.equal(fs.existsSync('./should-not-exist.txt'), false); + t.equal(fs.existsSync(envs.FILENAME), true, 'should exist: ' + envs.FILENAME); + t.end(); }); diff --git a/test/server.js b/test/server.js index fc4d6f2..14d34d1 100644 --- a/test/server.js +++ b/test/server.js @@ -19,6 +19,7 @@ module.exports.startServer = function startServer(port, emitter) { // Send back the request headers so the test can validate that the // x-forwarded-* headers were set. response.write(JSON.stringify({ + server: server.address(), request: { headers: request.headers } @@ -42,7 +43,6 @@ module.exports.startServer = function startServer(port, emitter) { server.listen(port, '127.0.0.1'); emitter.once('killall', function () { - server.close(); for (var socketId in sockets) { sockets[socketId].destroy(); } diff --git a/test/start-failures.test.sh b/test/start-failures.test.sh new file mode 100755 index 0000000..f1224ae --- /dev/null +++ b/test/start-failures.test.sh @@ -0,0 +1,15 @@ +#!/bin/bash +DIR=$(dirname "${BASH_SOURCE[0]}") +source $DIR/common.sh + +NF="$DIR/../nf.js" + +rm -rf $DIR/sandbox +mkdir -p $DIR/sandbox + +assert_file <(node $NF --procfile $DIR/fixtures/nocmd.Procfile start 2>&1) \ + "Syntax Error in Procfile, Line 1: No Command Found" +assert_file <(node $NF --procfile $DIR/fixtures/nokey.Procfile start 2>&1) \ + "Syntax Error in Procfile, Line 1: No Prockey Found" +assert_file <(cd $DIR && node ../nf.js --procfile $DIR/fixtures/nokey.Procfile start 2>&1) \ + "No Procfile and no package.json file found in Current Directory" diff --git a/test/start-honours-env-port.test.sh b/test/start-honours-env-port.test.sh index 50f74df..945273f 100755 --- a/test/start-honours-env-port.test.sh +++ b/test/start-honours-env-port.test.sh @@ -1,4 +1,6 @@ #!/bin/bash +cd $(dirname "${BASH_SOURCE[0]}") +source common.sh NF="node ../nf.js" @@ -8,8 +10,6 @@ mkdir -p sandbox PORT=4000 node ../nf.js --procfile fixtures/Procfile.port --env fixtures/env.empty start > sandbox/ports.txt # default is 5000, actual environment specifies 4000 -grep -q -F -e 4000 sandbox/ports.txt && \ - grep -q -F -e 4100 sandbox/ports.txt && \ - grep -q -F -e 4200 sandbox/ports.txt && exit 0 - -exit 1 +assert_file sandbox/ports.txt 4000 +assert_file sandbox/ports.txt 4100 +assert_file sandbox/ports.txt 4200 diff --git a/test/start-honours-port.test.sh b/test/start-honours-port.test.sh index fe1473f..f154e48 100755 --- a/test/start-honours-port.test.sh +++ b/test/start-honours-port.test.sh @@ -1,4 +1,6 @@ #!/bin/bash +cd $(dirname "${BASH_SOURCE[0]}") +source common.sh NF="node ../nf.js" @@ -8,8 +10,6 @@ mkdir -p sandbox node ../nf.js --procfile fixtures/Procfile.port --env fixtures/env.port start > sandbox/ports.txt # default is 5000, env.port specifies 3000 -grep -q -F -e 3000 sandbox/ports.txt && \ - grep -q -F -e 3100 sandbox/ports.txt && \ - grep -q -F -e 3200 sandbox/ports.txt && exit 0 - -exit 1 +assert_file sandbox/ports.txt 3000 +assert_file sandbox/ports.txt 3100 +assert_file sandbox/ports.txt 3200