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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ smf-test
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ smf-test
+
+
+
+
+
+
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ smf-test
+
+
+
+
+
+
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