From b6388a86cf7a87784f1e2aaa5b07b5cd819eee30 Mon Sep 17 00:00:00 2001 From: nelsonic Date: Fri, 27 Mar 2015 18:14:49 +0000 Subject: [PATCH] adds tests but unable to get above 92% coverage ... https://github.com/nelsonic/ps-tree/issues/1 --- .gitignore | 29 ++++++++++++++-- index.js | 15 +++++---- package.json | 34 ++++++++++++++++--- test/direct.js | 21 ++++++++++++ test/exec/child.js | 9 +++++ test/exec/parent.js | 15 +++++++++ test/test.js | 80 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 189 insertions(+), 14 deletions(-) mode change 100644 => 100755 index.js create mode 100644 test/direct.js create mode 100644 test/exec/child.js create mode 100644 test/exec/parent.js create mode 100644 test/test.js diff --git a/.gitignore b/.gitignore index 13abef4..59d842b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,28 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- node_modules -node_modules/* -npm_debug.log + +# Users Environment Variables +.lock-wscript diff --git a/index.js b/index.js old mode 100644 new mode 100755 index 3203103..3023de7 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -var spawn = require('child_process').spawn, +var spawn = require('child_process').spawn, es = require('event-stream'); module.exports = childrenOfPid @@ -6,11 +6,12 @@ module.exports = childrenOfPid function childrenOfPid( pid, callback) { var headers = null; - if('function' !== typeof callback) + if('function' !== typeof callback) throw new Error('childrenOfPid(pid, callback) expects callback') - if('number' == typeof pid) + if('number' == typeof pid) { pid = pid.toString() - + } + es.connect( spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm']).stdout, es.split(), @@ -20,7 +21,7 @@ function childrenOfPid( pid, callback) { headers = columns else { var row = {} - //for each header, + //for each header, var h = headers.slice() while (h.length) { row[h.shift()] = h.length ? columns.shift() : columns.join(' ') @@ -37,7 +38,7 @@ function childrenOfPid( pid, callback) { children.push(proc) } }) - callback(null, children) + callback(null, children) }) ).on('error', callback) } @@ -46,4 +47,4 @@ if(!module.parent) { childrenOfPid(process.argv[2] || 1, function (err, data) { console.log(data) }) -} \ No newline at end of file +} diff --git a/package.json b/package.json index 834d90e..f7adee5 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,36 @@ { "name": "ps-tree" -, "version": "0.0.3" -, "description": "get all children of a pid" +, "version": "0.0.4" +, "description": "Get all children of a pid" , "homepage": "http://github.com/indexzero/ps-tree" -, "repository": +, "repository": { "type": "git" - , "url": "https://github.com/indexzero/ps-tree.git" } +, "url": "https://github.com/indexzero/ps-tree.git" } , "dependencies": { "event-stream": "~0.5" } , "author": "Charlie Robbins" -} \ No newline at end of file +, "directories": { + "test": "test" + } +, "scripts": { + "quick": "./node_modules/tape/bin/tape ./test/*.js" +, "test": "./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape ./test/*.js" +, "direct": "./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape ./test/direct.js" +, "coverage": "./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape ./test/*.js && ./node_modules/.bin/istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100" +, "jshint": "./node_modules/jshint/bin/jshint -c .jshintrc --exclude-path .gitignore ." +, "codeclimate": "CODECLIMATE_REPO_TOKEN=ee15cc1e740638c273889ceb2cf1e3b2769697a6860760ba40c4df328e2a5a90 ./node_modules/codeclimate-test-reporter/bin/codeclimate.js < ./coverage/lcov.info" + } +, "devDependencies": { + "chalk": "^1.0.0" +, "codeclimate-test-reporter": "0.0.4" +, "ignored": "^2.0.2" +, "istanbul": "^0.3.4" +, "jshint": "^2.5.10" +, "mkdirp": "^0.5.0" +, "pre-commit": "0.0.9" +, "tape": "^3.0.3" + } +, "engines": { + "node": ">=0.10" + } +} diff --git a/test/direct.js b/test/direct.js new file mode 100644 index 0000000..6a0a407 --- /dev/null +++ b/test/direct.js @@ -0,0 +1,21 @@ +var test = require('tape'); +var chalk = require('chalk'); +var red = chalk.red, green = chalk.green, cyan = chalk.cyan; + +var cp = require('child_process'); +// var fs = require('fs'); +// fs.chmodSync('./index.js', 777); + +test(cyan('Directly Execute index.js without requiring the module'), function (t) { + var first = cp.exec("node -v", function(error, stdout, stderr) { + }) + var child = cp.exec("node ./index.js", function(error, data) { + console.log('data: ' + data.length); + if (error !== null) { + console.log(red('exec error: ' + error)); + } + }) + // console.log(first.pid) + t.true(child, green("✓ Called index.js directly. it worked.")); + t.end(); +}); diff --git a/test/exec/child.js b/test/exec/child.js new file mode 100644 index 0000000..8be694a --- /dev/null +++ b/test/exec/child.js @@ -0,0 +1,9 @@ +// a basic node http server +var port = Math.floor(Math.random() * 60000) + 1000; +// require('http').createServer(function (req, res) { +// res.writeHead(200, {"Content-Type": "text/html"}); +// res.end('Hai'); +// }).listen(port); +console.log("Visit: http://127.0.0.1:"+port); +console.log("process.id: "+process.pid); +console.log(" - - - - - - - - - - - - - - - - - - - - - - - "); diff --git a/test/exec/parent.js b/test/exec/parent.js new file mode 100644 index 0000000..759ab92 --- /dev/null +++ b/test/exec/parent.js @@ -0,0 +1,15 @@ +var cp = require('child_process'); +var chalk = require('chalk'); +var red = chalk.red, green = chalk.green, cyan = chalk.cyan; +var count = 0; +while(count < 2) { + 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)); + } + }) + console.log("child pid: "+child.pid + " | count: "+count); + count++ +} diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..e130ce8 --- /dev/null +++ b/test/test.js @@ -0,0 +1,80 @@ +var test = require('tape'); +var chalk = require('chalk'); +var red = chalk.red, green = chalk.green, cyan = chalk.cyan; + +var cp = require('child_process'), + psTree = require('../') + +test(cyan('Spawn a Parent Process which has a Two Child Processes'), function (t) { + var child = cp.exec("node ./test/exec/parent.js", function(error, stdout, stderr) { + }) + setTimeout(function(){ + psTree(child.pid, function (err, children) { + if(err){ + console.log(err); + } + console.log("Children: ", children, '\n'); + t.equal(children.length, 2, green("✓ There are "+children.length+" active child processes")); + cp.spawn('kill', ['-9'].concat(children.map(function (p) { return p.PID }))) + }) + },100); // using setTimeout to ensure the child process gets started + + setTimeout(function(){ + psTree(child.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")); + t.end(); + }) + },200); // ensure the child process was both started and killed by psTree +}); + +test(cyan('Attempt to call psTree without supplying a Callback'), function (t) { + var child = cp.exec("node ../index.js 12345", function(error, stdout, stderr) { + }) + var errmsg = "Error: childrenOfPid(pid, callback) expects callback" + setTimeout(function(){ + try { + psTree(child.pid); // attempt to call psTree without a callback + } + catch(e){ + console.log(red(e)); + t.equal(e.toString(), errmsg, green("✓ Fails when no callback supplied (as expected)")) + } + t.end(); + + },100); // using setTimeout to ensure the child process gets started +}); + + +test(cyan('Spawn a Child Process'), function (t) { + var first = cp.exec("node ./test/exec/child.js", function(error, stdout, stderr) { + }) + var child = cp.exec("node ../index.js '"+first.pid +"'", function(error, stdout, stderr) { + }) + setTimeout(function(){ + psTree(first.pid, function (err, children) { + if(err){ + console.log(err); + } + // console.log("Children: ", children, '\n'); + // t.equal(children.length, 2, green("✓ There are "+children.length+" active child processes")); + cp.spawn('kill', ['-9'].concat(children.map(function (p) { return p.PID }))) + }) + },100); // using setTimeout to ensure the child process gets started + + setTimeout(function(){ + psTree(child.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")); + t.end(); + }) + },200); // ensure the child process was both started and killed by psTree +});