Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 18 additions & 35 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
# http://www.appveyor.com/docs/appveyor-yml

# Fix line endings in Windows. (runs before repo cloning)
init:
- git config --global core.autocrlf true

# Test against these versions of Node.js.
build: off
version: '{build}'
environment:
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.12"
- nodejs_version: "4.2"
- nodejs_version: "6.2"

matrix:
allow_failures:
- nodejs_version: 0.10
- nodejs_version: 0.12

# Install scripts. (runs after repo cloning)
- nodejs_version: '10'
- nodejs_version: '8'
- nodejs_version: '6'
- nodejs_version: '4'
- nodejs_version: '0.12'
- nodejs_version: '0.10'
platform:
- x86
- x64
cache:
- node_modules
install:
- git rev-parse HEAD
# Get the latest stable version of Node 0.STABLE.latest
- ps: Install-Product node $env:nodejs_version
# Typical npm stuff.
- md C:\nc
- npm config set cache C:\nc
- npm version
- npm install

# Post-install test scripts.
test_script:
# Output useful info for debugging.
- npm version
- cmd: npm test

# Don't actually build.
build: off

# Set build version format here instead of in the admin panel.
version: "{build}"
- node --version
- npm --version
- npm test
after_test:
- npm run coverage
33 changes: 17 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
sudo: false
language: node_js
node_js:
- "0.10"
- "0.12"
- "4.4"
- "6.2"
- '10'
- '8'
- '6'
- '4'
- '0.12'
- '0.10'
os:
- linux
- centos
- macosx

before_install:
- travis_retry npm install -g [email protected]
- travis_retry npm install

- osx
cache:
directories:
- node_modules
install:
- npm install
script:
- node --version
- npm --version
- npm test

matrix:
allow_failures:
- node_js: "0.10"
- node_js: "0.12"
after_success:
- npm run coverage
7 changes: 4 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ module.exports = function childrenOfPid(pid, callback) {
return cb(null, row);
}),
es.writeArray(function (err, ps) {
var parents = [pid],
var parents = {},
children = [];

parents[pid] = true;
ps.forEach(function (proc) {
if (parents.indexOf(proc.PPID) !== -1) {
parents.push(proc.PID)
if (parents[proc.PPID]) {
parents[proc.PID] = true;
children.push(proc)
}
});
Expand Down
23 changes: 7 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,17 @@
"node": ">= 0.10"
},
"scripts": {
"_comment": "https://github.com/gotwarlost/istanbul#usage-on-windows",
"test": "istanbul cover node_modules/tape/bin/tape test/test.js test/direct.js",
"coverage": "npm test && istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100",
"codeclimate": "cross-env CODECLIMATE_REPO_TOKEN=84436b4f13c70ace9c62e7f04928bf23c234eb212c0232d39d7fb1535beb2da5 codeclimate < coverage/lcov.info"
"test": "istanbul cover node_modules/tape/bin/tape test/test.js",
"coverage": "cross-env CODECLIMATE_REPO_TOKEN=84436b4f13c70ace9c62e7f04928bf23c234eb212c0232d39d7fb1535beb2da5 node_modules/.bin/codeclimate-test-reporter < coverage/lcov.info"
},
"dependencies": {
"event-stream": "=3.3.4"
},
"devDependencies": {
"chalk": "^1.0.0",
"codeclimate-test-reporter": "0.0.4",
"cross-env": "^1.0.8",
"istanbul": "^0.3.20",
"pre-commit": "0.0.9",
"precommit": "^1.1.5",
"tape": "^3.0.3",
"codeclimate-test-reporter": "^0.5.0",
"cross-env": "^2.0.1",
"istanbul": "^0.4.5",
"tape": "^4.9.0",
"tree-kill": "^1.1.0"
},
"pre-commit": [
"coverage",
"codeclimate"
]
}
}
20 changes: 0 additions & 20 deletions test/direct.js

This file was deleted.

13 changes: 6 additions & 7 deletions test/exec/child.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// does nothing child process
console.log("Child process.id: " + process.pid);
console.log(" - - - - - - - - - - - - - - - - - - - - - - - ");

setTimeout(function () {
/* Does nothing, but prevents exit */
}, 1000);
var started = false;
setInterval(function() {
if (started) return;
console.log(process.pid);
started = true;
}, 100); // Does nothing, but prevents exit
29 changes: 15 additions & 14 deletions test/exec/parent.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
var path = require('path');
var cp = require('child_process');
var chalk = require('chalk');
var red = chalk.red
var green = chalk.green
var cyan = chalk.cyan;
var count = 0;

while(count < 10) {
var child = cp.exec("node ./test/exec/child.js", function(error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log(red('stderr: ' + stderr));
if (error !== null) {
console.log(red('exec error: ' + error));
}
})
var started = false;
var spawned = {};

console.log("child pid: %s | count: %s", child.pid, ++count);
for (var i = 0; i < 10; i++) {
var child = cp.spawn('node', [path.join('test', 'exec', 'child.js')]);
child.stdout.on('data', function (child) {
spawned[child.pid] = true;
}.bind(this, child));
}

setInterval(function() {
if (started) return;
if (Object.keys(spawned).length !== 10) return;
console.log(process.pid);
started = true;
}, 100); // Does nothing, but prevents exit
118 changes: 72 additions & 46 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,96 @@
var path = require('path');
var test = require('tape');
var chalk = require('chalk');
var cp = require('child_process');

var test = require('tape');
var treeKill = require('tree-kill');
var psTree = require('../');

var red = chalk.red,
green = chalk.green,
cyan = chalk.cyan;
var psTree = require('../');

var scripts = {
parent: path.join(__dirname, 'exec', 'parent.js'),
child: path.join(__dirname, 'exec', 'child.js')
};

test(cyan('Spawn a Parent process which has a Two Child Processes'), function (t) {
var parent = cp.exec('node ' + scripts.parent, function (error, stdout, stderr) {});
test('Spawn a Parent process which has ten Child processes', function (t) {
t.timeoutAfter(10000);
var parent = cp.spawn('node', [scripts.parent]);

setTimeout(function () {
psTree(parent.pid, function (err, children) {
if (err) { console.log(err); }
console.log(red('Children: '), children, '\n');
t.true(children.length > 0, green('✓ There are ' + children.length + ' active child processes'));
treeKill(parent.pid);
parent.stdout.on('data', function (data) {
psTree(parent.pid, function (error, children) {
if (error) {
t.error(error);
t.end();
return;
}

t.equal(children.length, 10, 'There should be 10 active child processes');
if (children.length !== 10) {
t.comment(parent.pid.toString());
t.comment(JSON.stringify(children, null, 2));
}

treeKill(parent.pid, function(error) {
if (error) {
t.error(error);
t.end();
return;
}
t.end();
});
});
});
});

setTimeout(function () {
psTree(parent.pid, function (err, children) {
if (err) { console.log(err); }
// console.log('Children: ', children, '\n');
// console.log(' ')
t.equal(children.length, 0, green('✓ No more active child processes (we killed them)'));
test('Spawn a Child Process which has zero Child processes', function (t) {
t.timeoutAfter(10000);
var child = cp.spawn('node', [scripts.child]);

child.stdout.on('data', function (data) {
psTree(child.pid, function (error, children) {
if (error) {
t.error(error);
t.end();
return;
}

t.equal(children.length, 0, 'There should be no active child processes');
if (children.length !== 0) {
t.comment(child.pid.toString());
t.comment(JSON.stringify(children, null, 2));
}

treeKill(child.pid, function(error) {
if (error) {
t.error(error);
t.end();
return;
}
t.end();
});
}, 2000); // give psTree time to kill the processes
}, 500); // give the child process time to spawn
// need more time on a slow(or heavy load server). maybe promise.then is better instead of the timeout
});
});
});

test(cyan('FORCE ERROR by calling psTree without supplying a Callback'), function (t) {
var errmsg = 'Error: childrenOfPid(pid, callback) expects callback'
test('Call psTree without supplying a Callback', function (t) {
var errmsg = 'Error: childrenOfPid(pid, callback) expects callback';

// Attempt to call psTree without a callback
try { psTree(1234); }
catch (e) {
t.equal(e.toString(), errmsg, green('✓ Fails when no callback supplied (as expected)'))
try {
psTree(1234);
} catch (e) {
t.equal(e.toString(), errmsg);
}

t.end();
});


test(cyan('Spawn a Child Process and psTree with a String as pid'), function (t) {
var child = cp.exec('node ' + scripts.child, function(error, stdout, stderr) {});
setTimeout(function(){
psTree(child.pid.toString(), function (err, children) {
if (err) { console.log(err); }
// cp.spawn('kill', ['-9'].concat(children.map(function (p) { return p.PID })))
treeKill(child.pid);
});

setTimeout(function() {
psTree(child.pid.toString(), function (err, children) {
if (err) { console.log(err); }
t.equal(children.length, 0, green('✓ No more active child processes'));
t.end();
});
}, 1000); // give psTree time to kill the processes
}, 200); // give the child process time to spawn
test('Directly Execute bin/ps-tree.js', function (t) {
var child = cp.exec('node ./bin/ps-tree.js', function (error, data) {
if (error !== null) {
t.error(err);
t.end();
return;
}
t.end();
});
});