diff --git a/.gitignore b/.gitignore
index 5743ba4..b512c09 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
-test
node_modules
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
index a596fdc..a267a83 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,4 +1,3 @@
node_modules
.gitignore
-test
screenshots
\ No newline at end of file
diff --git a/README.md b/README.md
index 546bfb3..ae88d82 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-pm2-gui [](http://badge.fury.io/js/pm2-gui)
+pm2-gui [](http://badge.fury.io/js/pm2-gui) [](https://travis-ci.org/Tjatse/pm2-gui)
=======
An elegant web interface for Unitech/PM2.
-> Compatible with PM2 v0.12.2.
+> Compatible with PM2 v0.12.3.
# Guide
- [Features](#feats)
@@ -14,7 +14,6 @@ An elegant web interface for Unitech/PM2.
- [Configs](#cli_confs)
- [Authorization](#auth)
- [UI/UX](#ui)
-- [TODO](#todo)
# Feature
@@ -74,24 +73,40 @@ $ npm install -g pm2-gui
Options:
- -h, --help output usage information
+ -h, --help output usage information
+ --config [file] pass JSON config file with options
--no-debug hide stdout/stderr information
+ --config path to custom .json config. Default value pm2-gui.json
```
## Configs
```javascript
{
- "refresh": 3000
- "manipulation": true
- "pm2": "~/.pm2"
+ "refresh": 3000,
+ "manipulation": true,
+ "pm2": "~/.pm2",
+ "port": 8088
}
```
- **refresh** The heartbeat duration of monitor (backend), `5000` by default.
-- **manupulation** A value indicates whether the client has permission to restart/stop processes, `true` by default.
+- **manipulation** A value indicates whether the client has permission to restart/stop processes, `true` by default.
- **pm2** Root directory of Unitech/PM2, `~/.pm2` by default.
-- **password** The encrypted authentication code, if this config is set, users need to be authorized before accessing the index page.
+- **password** The encrypted authentication code, if this config is set, users need to be authorized before accessing the index page, `password` could only be set by `pm2-gui set password [password]`.
+- **port** Web GUI port, can be set only from config file
+
+### Config file
+You can quit set configurations by `pm2-gui start --config [file]`, the `[file]` must be an valid JSON, and can including all the above keys.
+
+Example
+```bash
+# Load the JSON configured file which is named as `pm2-gui.json` in current directory.
+$ pm2-gui start --config
+
+# Load the specific JSON configured file in current directory.
+$ pm2-gui start --config conf.json
+```
### Set Config
Usage
@@ -168,15 +183,6 @@ Tail Logs

-
-# TODO
-- [x] Authentication
-- [ ] Multiple operations.
-- [ ] Configured JSON files.
-- [ ] Memory and CPU usage gauge of each process.
-- [ ] Test on Internet Explorer (need environment && PRs).
-- [ ] Need feedback/test.
-
## License
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/bin/pm2-gui b/bin/pm2-gui
index 2b93160..d1913ee 100755
--- a/bin/pm2-gui
+++ b/bin/pm2-gui
@@ -2,6 +2,7 @@
var commander = require('commander'),
path = p = require('path'),
+ fs = require('fs'),
chalk = require('chalk'),
_ = require('lodash'),
pkg = require('../package.json'),
@@ -21,31 +22,38 @@ commander.on('--help', function(){
chalk.grey(' $ pm2-gui start 8090\n')
);
});
-commander.on('-c', function(){
- console.log(arguments);
-})
-
-// Web interface
+/**
+ * Run web interface.
+ */
commander.command('start [port]')
- .option('--no-debug', 'hide stdout/stderr information')
+ .option('--config [file]', 'pass JSON config file with options')
+ .option('--no-debug', 'hide stdout / stderr information')
.description('Launch the web server, port default by 8088')
.action(function(port, cmd){
- interface(port, cmd.debug);
- });
+ if (cmd.config) {
+ var jsonFile;
+ if (typeof cmd.config != 'string') {
+ jsonFile = 'pm2-gui.json';
+ } else {
+ jsonFile = cmd.config;
+ }
+ if (!fs.existsSync(jsonFile)) {
+ console.log(chalk.red('✘ JSON configured file does not exist!\n'));
+ process.exit();
+ }
-// Configuration
-var acceptKeys = ['pm2', 'refresh', 'manipulation', 'password'];
-function showConfigs(cmd, mon){
- if (!mon) {
- mon = Monitor();
- }
- var storage = mon._config.store, prints = '';
- for (var k in storage) {
- prints += Array(15 - k.length).join(' ') + chalk.bold(k + ': ') + ' ' + chalk.blue(storage[k] + '\n');
- }
- console.log(prints);
-}
+ try {
+ var config = JSON.parse(fs.readFileSync(jsonFile, {encoding: 'utf-8'}));
+ setConfig(config);
+ } catch (err) {
+ console.log(chalk.red('✘ JSON configured file is invalid!\n'));
+ process.exit();
+ }
+ }
+ port && setConfig('port', port);
+ interface(cmd.debug);
+ });
commander.command('config')
.description('show all configs')
@@ -54,19 +62,8 @@ commander.command('config')
commander.command('set ')
.description('set config by key-value pairs')
.action(function(key, value, cmd){
- if (!~acceptKeys.indexOf(key)) {
- return console.log('key could only be one of below:', acceptKeys.map(function(m){
- return '\n' + chalk.magenta(m)
- }).join(''));
- }
- var mon = Monitor();
- if (key == acceptKeys[acceptKeys.length - 1]) {
- var md5 = crypto.createHash('md5');
- md5.update(value);
- value = md5.digest('hex');
- }
- mon.config(key, value);
- showConfigs(cmd, mon);
+ var mon = setConfig(key, value);
+ mon && showConfigs(cmd, mon);
});
commander.command('rm ')
@@ -82,4 +79,51 @@ commander.parse(process.argv);
if (process.argv.length == 2) {
commander.outputHelp();
process.exit(0);
+}
+
+/**
+ * Set configuration.
+ * @param key
+ * @param value
+ * @returns {*}
+ */
+function setConfig(key, value){
+ var mon = Monitor(),
+ acceptKeys = Object.keys(mon.options).filter(function(key){
+ return !~['socketio', 'pm2Conf', 'debug'].indexOf(key);
+ });
+
+ (function config(pairs){
+ if (pairs.length == 0) {
+ return;
+ }
+ var pair = pairs.shift();
+ if (!~acceptKeys.indexOf(pair[0])) {
+ return config(pairs);
+ }
+ if (pair[0] == 'password') {
+ var md5 = crypto.createHash('md5');
+ md5.update(pair[1]);
+ pair[1] = md5.digest('hex');
+ }
+ mon.config(pair[0], pair[1]);
+ config(pairs);
+ })(typeof key == 'object' ? _.pairs(key) : [[key, value]]);
+
+ return mon;
+}
+/**
+ * Show all configurations.
+ * @param cmd
+ * @param mon
+ */
+function showConfigs(cmd, mon){
+ if (!mon) {
+ mon = Monitor();
+ }
+ var storage = mon._config.store, prints = '';
+ for (var k in storage) {
+ prints += Array(15 - k.length).join(' ') + chalk.bold(k + ': ') + ' ' + chalk.blue(storage[k] + '\n');
+ }
+ console.log(prints);
}
\ No newline at end of file
diff --git a/lib/mon.js b/lib/mon.js
index 17c728c..9c57d1b 100644
--- a/lib/mon.js
+++ b/lib/mon.js
@@ -8,7 +8,8 @@ var fs = require('fs'),
ansiHTML = require('ansi-html'),
pm = require('./pm'),
totalmem = require('os').totalmem(),
- pidusage = require('pidusage');
+ pidusage = require('pidusage'),
+ defConf = require('../pm2-gui.conf');
module.exports = Monitor;
@@ -33,30 +34,34 @@ function Monitor(options){
this._init(options);
};
+Monitor.prototype._resolveHome = function(pm2Home){
+ if (pm2Home.indexOf('~/') == 0) {
+ // Get root directory of PM2.
+ pm2Home = process.env.PM2_HOME || p.resolve(process.env.HOME || process.env.HOMEPATH, pm2Home.substr(2));
+
+ // Make sure exist.
+ if (!pm2Home || !fs.existsSync(pm2Home)) {
+ throw new Error('PM2 root can not be located, try to set env by `export PM2_HOME=[ROOT]`.');
+ }
+ }
+ return pm2Home;
+}
/**
* Initialize options and configurations.
* @private
*/
Monitor.prototype._init = function(options){
options = options || {};
+
// bind default options.
- _.defaults(options, {
- refresh : 5000,
- manipulation: true
- });
+ options = _.defaults(defConf, options);
- // Get root directory of PM2.
- var pm2Root = process.env.PM2_HOME || p.resolve(process.env.HOME || process.env.HOMEPATH, '.pm2');
-
- // Make sure exist.
- if (!pm2Root || !fs.existsSync(pm2Root)) {
- throw new Error('PM2 root can not be located, try to set env by `export PM2_HOME=[ROOT]`.');
- }
+ options.pm2 = this._resolveHome(options.pm2);
// Load PM2 config.
- var pm2ConfPath = path.join(pm2Root, 'conf.js');
+ var pm2ConfPath = path.join(options.pm2, 'conf.js');
try {
- options.pm2Conf = require(pm2ConfPath)(pm2Root);
+ options.pm2Conf = require(pm2ConfPath)(options.pm2);
if (!options.pm2Conf) {
throw new Error(404);
}
@@ -64,8 +69,6 @@ Monitor.prototype._init = function(options){
throw new Error('Can not load PM2 config, the file "' + pm2ConfPath + '" does not exist.');
}
- options.pm2Root = pm2Root;
-
// Bind socket.io server to context.
if (options.sockio) {
this._sockio = options.sockio;
@@ -77,12 +80,18 @@ Monitor.prototype._init = function(options){
Object.freeze(this.options);
// Initialize configurations.
- this._config = new nconf.File({file: path.resolve(this.options.pm2Root, 'pm2-gui.json')});
+ this._config = new nconf.File({file: path.resolve(this.options.pm2, 'pm2-gui.json')});
// Set configurations.
- this.config('pm2', this._config.get('pm2') || this.options.pm2Root);
- this.config('refresh', this._config.get('refresh') || this.options.refresh);
- this.config('manipulation', this._config.get('manipulation') || this.options.manipulation || true);
+ this.config('pm2', this._resolveHome(this.config('pm2')) || this.options.pm2);
+ this.config('refresh', this.config('refresh') || this.options.refresh);
+ this.config('port', this.config('port') || this.options.port || 8088);
+
+ var mani = false;
+ if (typeof (mani = this.config('manipulation')) == 'undefined' && typeof (mani = this.options.manipulation) == 'undefined') {
+ mani = true;
+ }
+ this.config('manipulation', mani);
// Logger.
this._log = Debug({
@@ -115,12 +124,8 @@ Monitor.prototype.config = function(key, value){
// Clear config.
this._config.clear(key);
// Reset to default if necessary.
- if (key == 'refresh') {
- value = 5000;
- } else if (key == 'manipulation') {
- value = true;
- }
- value && this._config.set(key, value);
+ var value = defConf[key];
+ (typeof value != 'undefined') && this._config.set(key, value);
return this._config.saveSync();
}
@@ -132,6 +137,7 @@ Monitor.prototype.config = function(key, value){
value = (value == 'true');
}
}
+
this._config.set(key, value);
// Save it.
this._config.saveSync();
@@ -350,8 +356,8 @@ Monitor.prototype._connectProcSock = function(socket){
stat.memory = stat.memory * 100 / totalmem;
// Emit memory/CPU usage to clients.
broadcast.call(ctx, {
- pid : pid,
- time: Date.now(),
+ pid : pid,
+ time : Date.now(),
usage: stat
});
});
diff --git a/package.json b/package.json
index 432c5b8..6613c60 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,7 @@
"version": "0.0.7",
"description": "An elegant web interface for Unitech/PM2.",
"scripts": {
+ "test": "NODE_ENV=test bash test/index.sh"
},
"bin": {
"pm2-gui": "bin/pm2-gui"
diff --git a/pm2-gui.conf b/pm2-gui.conf
new file mode 100644
index 0000000..d458811
--- /dev/null
+++ b/pm2-gui.conf
@@ -0,0 +1,6 @@
+module.exports = {
+ "pm2": "~/.pm2",
+ "refresh": 5000,
+ "manipulation": true,
+ "port": 8088
+};
\ No newline at end of file
diff --git a/test/bash/config.sh b/test/bash/config.sh
new file mode 100644
index 0000000..e9e2aef
--- /dev/null
+++ b/test/bash/config.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+SRC=$(cd $(dirname "$0"); pwd)
+source "${SRC}/include.sh"
+
+cd $fixtures
+
+head "set config (Number)(refresh)"
+$pg set refresh 4000 > /dev/null
+val=`$pg config | grep "refresh:" | egrep -oh "\d+"`
+
+[ $val -eq 4000 ] || fail "expect the value to be 4000, but current is $val"
+success "the value should be 4000"
+
+head "set config (Number)(port)"
+$pg set port 9000 > /dev/null
+val=`$pg config | grep "port:" | egrep -oh "\d+"`
+
+[ $val -eq 9000 ] || fail "expect the value to be 9000, but current is $val"
+success "the value should be 9000"
+
+head "set config (Boolean)"
+$pg set manipulation false > /dev/null
+val=`$pg config | grep "manipulation:" | egrep -oh "(true|false)"`
+
+[ $val = false ] || fail "expect the value to be false, but current is $val"
+success "the value should be false"
+
+head "set config (String)"
+tmpPM2="/tmp/.pm2"
+
+if [ ! -d "$tmpPM2" ]; then
+ mkdir "$tmpPM2"
+fi
+
+$pg set pm2 "$tmpPM2" > /dev/null
+val=`$pg config | grep "pm2:" | egrep -oh "$tmpPM2$" | wc -c`
+
+[ $val -gt 0 ] || fail "expect the value to be /tmp/.pm2"
+success "the value should be /tmp/.pm2"
+
+$pg set pm2 "~/.pm2" > /dev/null
+$pg set port 8088 > /dev/null
diff --git a/test/bash/include.sh b/test/bash/include.sh
new file mode 100644
index 0000000..4969547
--- /dev/null
+++ b/test/bash/include.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+
+node="`type -P node`"
+nodeVersion="`$node -v`"
+
+pg="`type -P node` `pwd`/bin/pm2-gui"
+
+fixtures="test/fixtures"
+
+function success {
+ echo -e "\033[32m ✔ $1\033[0m"
+}
+
+function fail {
+ echo -e "######## \033[31m ✘ $1\033[0m"
+ exit 1
+}
+
+function spec {
+ RET=$?
+ sleep 0.3
+ [ $RET -eq 0 ] || fail "$1"
+ success "$1"
+}
+
+function ispec {
+ RET=$?
+ sleep 0.3
+ [ $RET -ne 0 ] || fail "$1"
+ success "$1"
+}
+
+function should {
+ sleep 0.5
+ OUT=`$pm2 prettylist | grep -o "$2" | wc -l`
+ [ $OUT -eq $3 ] || fail "$1"
+ success "$1"
+}
+
+function head {
+ echo -e "\x1B[1;35m$1\x1B[0m"
+}
diff --git a/test/bash/interface.sh b/test/bash/interface.sh
new file mode 100644
index 0000000..055a7b5
--- /dev/null
+++ b/test/bash/interface.sh
@@ -0,0 +1,114 @@
+#!/usr/bin/env bash
+
+SRC=$(cd $(dirname "$0"); pwd)
+source "${SRC}/include.sh"
+
+cd $fixtures
+
+$pg set port 8088 > /dev/null
+
+head "run web server (default port)"
+nohup $pg start > /dev/null 2>&1 &
+pid=$!
+sleep 1
+ret=`nc 127.0.0.1 8088 < /dev/null; echo $?`
+[ $ret -eq 0 ] || fail "expect 127.0.0.1:8088 can be connected"
+success "127.0.0.1:8088 should be connected"
+
+kill "$pid"
+sleep 1
+
+ret=`nc 127.0.0.1 8088 < /dev/null; echo $?`
+[ $ret -eq 1 ] || fail "expect 127.0.0.1:8088 can not be connected"
+success "127.0.0.1:8088 should be disconnected"
+
+head "run web server (customized port: 9000)"
+nohup $pg start 9000 > /dev/null 2>&1 &
+pid=$!
+sleep 1
+ret=`nc 127.0.0.1 9000 < /dev/null; echo $?`
+[ $ret -eq 0 ] || fail "expect 127.0.0.1:9000 can be connected"
+success "127.0.0.1:9000 should be connected"
+
+kill "$pid"
+sleep 1
+
+ret=`nc 127.0.0.1 9000 < /dev/null; echo $?`
+[ $ret -eq 1 ] || fail "expect 127.0.0.1:9000 can not be connected"
+success "127.0.0.1:9000 should be disconnected"
+
+head "run web server (--config verify)"
+ret=`$pg start --config not_exist.json | grep "does not exist" | wc -c`
+[ $ret -gt 0 ] || fail "expect throw out error message"
+success "JSON file does not exist"
+
+ret=`$pg start --config invalid.conf | grep "invalid" | wc -c`
+[ $ret -gt 0 ] || fail "expect throw out error message"
+success "JSON file invalid"
+
+head "run web server (--config specific file)"
+nohup $pg start --config pm2-gui-cp.conf > /dev/null 2>&1 &
+pid=$!
+sleep 1
+ret=`nc 127.0.0.1 27130 < /dev/null; echo $?`
+[ $ret -eq 0 ] || fail "expect 127.0.0.1:27130 can be connected"
+success "127.0.0.1:27130 should be connected"
+
+kill "$pid"
+sleep 1
+
+ret=`nc 127.0.0.1 27130 < /dev/null; echo $?`
+[ $ret -eq 1 ] || fail "expect 127.0.0.1:27130 can not be connected"
+success "127.0.0.1:27130 should be disconnected"
+
+val=`$pg config | grep "refresh:" | egrep -oh "\d+"`
+[ $val -eq 3000 ] || fail "expect the value of refresh to be 3000, but current is $val"
+success "the value of refresh should be 3000"
+val=`$pg config | grep "manipulation:" | egrep -oh "(true|false)"`
+[ $val = false ] || fail "expect the value of manipulation to be false, but current is $val"
+success "the value of manipulation should be false"
+val=`$pg config | grep "pm2:" | egrep -oh "/tmp/\.pm2$" | wc -c`
+[ $val -gt 0 ] || fail "expect the value of pm2 to be /tmp/.pm2"
+success "the value of pm2 should be /tmp/.pm2"
+
+head "run web server (--config default file)"
+nohup $pg start --config > /dev/null 2>&1 &
+pid=$!
+sleep 1
+ret=`nc 127.0.0.1 8088 < /dev/null; echo $?`
+[ $ret -eq 0 ] || fail "expect 127.0.0.1:8088 can be connected"
+success "127.0.0.1:8088 should be connected"
+
+kill "$pid"
+sleep 1
+
+ret=`nc 127.0.0.1 8088 < /dev/null; echo $?`
+[ $ret -eq 1 ] || fail "expect 127.0.0.1:8088 can not be connected"
+success "127.0.0.1:8088 should be disconnected"
+
+val=`$pg config | grep "refresh:" | egrep -oh "\d+"`
+[ $val -eq 5000 ] || fail "expect the value of refresh to be 5000, but current is $val"
+success "the value of refresh should be 3000"
+val=`$pg config | grep "manipulation:" | egrep -oh "(true|false)"`
+[ $val = true ] || fail "expect the value of manipulation to be true, but current is $val"
+success "the value of manipulation should be true"
+root="~/.pm2"
+if [ -z "$PM2_HOME" ]
+then
+ root="$PM2_HOME"
+else
+ if [ -z "$HOME" ]
+ then
+ root="$HOME/.pm2"
+ else
+ if [ -z "$HOMEPATH" ]
+ then
+ root="$HOMEPATH/.pm2"
+ fi
+ fi
+fi
+val=`$pg config | grep "pm2:" | egrep -oh "$root$" | wc -c`
+[ $val -gt 0 ] || fail "expect the value of pm2 to be $root"
+success "the value of pm2 should be $root"
+
+$pg set port 8088 > /dev/null
\ No newline at end of file
diff --git a/test/fixtures/colorful.js b/test/fixtures/colorful.js
new file mode 100644
index 0000000..5aaa8d6
--- /dev/null
+++ b/test/fixtures/colorful.js
@@ -0,0 +1,14 @@
+var chalk = require('chalk');
+
+console.log('This is', chalk.bold.red('red'));
+console.log('This is', chalk.dim.green('green'));
+console.log('This is', chalk.bold.green('green'));
+console.log('This is', chalk.bold.italic.yellow('yellow'));
+console.log('This is', chalk.bold.strikethrough.blue('blue'));
+console.log('This is', chalk.bold.underline.magenta('magenta'));
+console.log('This is', chalk.bold.cyan('cyan'));
+console.log('This is', chalk.bold.grey('grey'));
+
+setTimeout(function(){
+
+}, 3000000);
\ No newline at end of file
diff --git a/test/fixtures/exit.js b/test/fixtures/exit.js
new file mode 100644
index 0000000..3e3afd3
--- /dev/null
+++ b/test/fixtures/exit.js
@@ -0,0 +1 @@
+console.log('ok at', Date.now());
\ No newline at end of file
diff --git a/test/fixtures/fib-slow.js b/test/fixtures/fib-slow.js
new file mode 100644
index 0000000..1b86182
--- /dev/null
+++ b/test/fixtures/fib-slow.js
@@ -0,0 +1,13 @@
+function fib(n){
+ if (n == 1) return 1;
+ if (n == 0) return 0;
+ if (n > 1) return fib(n - 2) + fib(n - 1)
+}
+
+function fi(){
+ console.log('fibonacci...');
+ var f = fib((parseInt(Math.random() * 10000) + 30) % 42);
+ console.log('is:', f);
+ setTimeout(fi, 1000);
+}
+fi();
diff --git a/test/fixtures/invalid.conf b/test/fixtures/invalid.conf
new file mode 100644
index 0000000..77d5015
--- /dev/null
+++ b/test/fixtures/invalid.conf
@@ -0,0 +1,5 @@
+{
+ "pm2": "/tmp/.pm2",
+ "refresh": 3000,
+ "manipulation":
+}
\ No newline at end of file
diff --git a/test/fixtures/pm2-gui-cp.conf b/test/fixtures/pm2-gui-cp.conf
new file mode 100644
index 0000000..fef69bb
--- /dev/null
+++ b/test/fixtures/pm2-gui-cp.conf
@@ -0,0 +1,6 @@
+{
+ "pm2": "/tmp/.pm2",
+ "refresh": 3000,
+ "manipulation": false,
+ "port": 27130
+}
\ No newline at end of file
diff --git a/test/fixtures/pm2-gui.json b/test/fixtures/pm2-gui.json
new file mode 100644
index 0000000..84e35f3
--- /dev/null
+++ b/test/fixtures/pm2-gui.json
@@ -0,0 +1,6 @@
+{
+ "pm2": "~/.pm2",
+ "refresh": 5000,
+ "manipulation": true,
+ "port": 8088
+}
\ No newline at end of file
diff --git a/test/fixtures/rand.js b/test/fixtures/rand.js
new file mode 100644
index 0000000..fe9081b
--- /dev/null
+++ b/test/fixtures/rand.js
@@ -0,0 +1,3 @@
+setInterval(function(){
+ console.log(Math.random());
+}, 3000);
\ No newline at end of file
diff --git a/test/fixtures/throw.js b/test/fixtures/throw.js
new file mode 100644
index 0000000..4149452
--- /dev/null
+++ b/test/fixtures/throw.js
@@ -0,0 +1,4 @@
+console.log('App started.');
+setTimeout(function(){
+ throw new Error('uncaughtException has been thrown.');
+}, 15000);
\ No newline at end of file
diff --git a/test/fixtures/tick.js b/test/fixtures/tick.js
new file mode 100644
index 0000000..9c3f4a8
--- /dev/null
+++ b/test/fixtures/tick.js
@@ -0,0 +1,4 @@
+var chalk = require('chalk');
+setInterval(function(){
+ console.log(chalk.bold.green('Tick'), Date.now());
+}, 1000);
\ No newline at end of file
diff --git a/test/fixtures/tock.js b/test/fixtures/tock.js
new file mode 100644
index 0000000..025b26f
--- /dev/null
+++ b/test/fixtures/tock.js
@@ -0,0 +1,6 @@
+var chalk = require('chalk');
+
+console.log(chalk.magenta('Tock every 5 seconds.'));
+setInterval(function(){
+ console.log(chalk.bold.red.underline('Tock'), Date.now());
+}, 5000);
\ No newline at end of file
diff --git a/test/index.sh b/test/index.sh
new file mode 100644
index 0000000..52e9da5
--- /dev/null
+++ b/test/index.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+SRC=$(cd $(dirname "$0"); pwd)
+source "${SRC}/bash/include.sh"
+
+set -e
+
+echo -e "\x1B[1m############ TEST SUITE ############\x1B[0m"
+echo -e "\x1B[1mpm2-gui Command = $pg\x1B[0m"
+echo -e "\x1B[1mNode version = $nodeVersion\x1B[0m"
+$node -e "var os = require('os'); console.log('\x1B[1march : %s\nplatform : %s\nrelease : %s\ntype : %s\nmem : %d\x1B[0m', os.arch(), os.platform(), os.release(), os.type(), os.totalmem())"
+echo -e "\x1B[1m############# FINISHED #############\x1B[0m"
+echo -e ""
+
+bash ./test/bash/config.sh
+bash ./test/bash/interface.sh
diff --git a/web/index.js b/web/index.js
index 670ee7b..b5ff82c 100644
--- a/web/index.js
+++ b/web/index.js
@@ -8,7 +8,7 @@ var express = require('express'),
module.exports = runServer;
-function runServer(port, debug){
+function runServer(debug){
var app = express();
// all environments
@@ -26,19 +26,16 @@ function runServer(port, debug){
// router
require('../lib/util/router')(app, log);
- if (!port || isNaN(port)) {
- port = 8088;
- }
-
var server = require('http').Server(app);
var io = require('socket.io')(server);
- server.listen(port);
- log.i('http', 'Web server of', chalk.bold.underline('Unitech/PM2'), 'is listening on port', chalk.bold(port));
var mon = Monitor({
sockio: io,
debug : !!debug
});
+ var port = mon.config('port');
+ server.listen(port);
+ log.i('http', 'Web server of', chalk.bold.underline('Unitech/PM2'), 'is listening on port', chalk.bold(port));
mon.run();
}
\ No newline at end of file