How to execute command from node application - javascript

I need to call to CMD command from my node JS application ,
is it possible ?
I try with the following (POC) and I got error
var express = require('express');
var app = express();
app.get('/', function (req, res) {
function cmd_exec(cmd, args, cb_stdout, cb_end) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args),
me = this;
me.exit = 0; // Send a cb to set 1 when cmd exits
child.stdout.on('data', function (data) {
cb_stdout(me, data)
});
child.stdout.on('end', function () {
cb_end(me)
});
}
foo = new cmd_exec('npm', 'install glob --save',
function (me, data) {
me.stdout += data.toString();
},
function (me) {
me.exit = 1;
}
);
setTimeout(
// wait 0.25 seconds and print the output
log_console,
250);
function log_console() {
console.log(foo.stdout);
}
res.send("Hello world");
});
I saw this code in the following link
node.js shell command execution
The error is :
TypeError: Incorrect value of args option
in line child = spawn(cmd, args),
what am I doing wrong here ?Currnlty I just use the npm install command(just for testing) but any other command that I can execute and run will be sufficient

When executing a terminal command, there are two parts: The command, and the arguments. In your case, the command is npm, and the arguments is everything that comes after that.
cmd_exec('npm', ['install', 'glob', '--save'],

Related

NodeJS - how to write to a file all the console.log?

On my CentOS 7.x server I am running Node (v6.7.0 and v0.10.36).
forever start /home/www/html/server/mynode.js
which runs following:
/usr/bin/node /home/www/html/server/mynode.js
CODE of mynode.js:
var http = require('http');
var net = require('net');
var url = require('url');
var io = require('socket.io').listen(3004);
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
try{
console.log(JSON.stringify(db));
} catch(dis) {
console.log(dis);
}
});
});
How do i tell NodeJS or Linux to keep log? So that i can listen whats going on by tail -f /var/log/mynode.log ?
You can overwrite your console.log
var fs = require('fs');
var trueLog = console.log;
console.log = function(msg) {
fs.appendFile("/tmp/log.log", msg, function(err) {
if(err) {
return trueLog(err);
}
});
//trueLog(msg); //uncomment if you want logs
}
Just put this snippet on top of your nodejs code.
There's an option for capturing logs
forever -o path/to/logfile start /home/www/html/server/mynode.js
From the docs -o OUTFILE Logs stdout from child script to OUTFILE

Mocha calling callback after done()

I am aiming for ease of use in my unit tests, I have created a master_test.js file that I will include below. In it, I simply require other test.js files as a function and run them. An issue I had is that Mocha does not detect any unit tests to be run unless I encase my startup in a describe() block, so I am forced to have a master describe encase my application to resolve that. My problem now is that in order to run the other tests, I have to call a callback() after a done(). Is there any easy way to fix my problem?
function app_setup() {
options.database = 'testing';
it('app launched successfully', function(done) {
require('../app.js').initialize(0, options, function(err, app) {
remove_all_entities(function() {
app.set('port', port);
var server = app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + server.address().port);
//ISSUE LOCATION, NEED TO CALL run_tests() callback after done()//
done();
run_tests();
});
});
});
});
}
function run_tests() {
var database = require('../database.js');
var entity_controller_test = require('./controllers/entity_controller_test.js').entity_controller_test;
var login_test = require('./controllers/login_test.js').login_test;
var token_access_test = require('./controllers/token_access_test.js').token_access_test;
var token_auth_test = require('./controllers/auth_token_test.js').token_auth_test;
var business_rules_insert = require('./business_rules/basic_database_rules.js').business_rules_insert_test;
var logout_test = require('./controllers/logout_test.js').logout_test;
var schema_override = require('./business_rules/schema_overrides').schema_overrides;
var aggregation_test = require('./entity_specific/aggregation').aggregation_test;
var tests = [login_test, aggregation_test, logout_test];
async.series(tests, function() {
test_teardown(done);
});
}
function test_teardown(done) {
remove_all_entities(done);
};

Share methods across processes in node.js

So I want to be able to share methods across different node.js processes created using the cluster module.
If I run the code below I can share the method server.handleRequest across the child processes, however If I uncomment //server.test(); in the second file and try to use the method test in the original process, node crashes.
"use strict";
var os = require('os');
var http = require('http');
var cluster = require('cluster');
function testMethod() {
console.log('Test');
}
function handleRequest(req, res) {
res.writeHead(200);
res.end("This answer comes from the process " + process.pid);
}
var createServer = function createServer(opts) {
var server = {};
server.test = testMethod;
server.handleRequest = handleRequest;
if (cluster.isMaster) {
var cpuCount = require('os').cpus().length;
for (var i = 0; i < cpuCount; i += 1) {
cluster.fork();
}
return server;
} else {
// Create HTTP server.
http.Server(function(req, res) {
server.handleRequest(req, res);
}).listen(8080);
}
}
module.exports = {
createServer: createServer,
};
The second file that includes the above file.
"use strict";
var router = require('./test.js');
var server = router.createServer();
//server.test();
But If I don't use the cluster module I can use the test method outside the factory function with out crashing. So how do I share methods created in factory functions across all node processes, while using the cluster module? And why do the child processes execute test when only the original process calls server.test()?
var http = require('http');
function testMethod() {
console.log('Test');
}
function handleRequest(req, res) {
res.writeHead(200);
res.end("This answer comes from the process " + process.pid);
}
var createServer = function createServer(opts) {
var server = {};
server.test = testMethod;
server.handleRequest = handleRequest;
http.Server(function(req, res) {
server.handleRequest(req, res);
}).listen(8080);
return server;
}
module.exports = {
createServer: createServer,
};

Rookie error while writing test with Chai, Mocha, Express, johnny-five and node

Hi there I'm trying to learn a bit of test driven development using express, mocha, chai and johnny-five. So I wrote this little application that can turn an LED on and off. The application works but my test fails. Can somebody tell me what I am doing wrong in my test?
Thank you
The output of npm test is
> blink#1.0.0 test /Users/me/Documents/johnny-five/blink
> mocha --reporter spec
1435257445439 Looking for connected device
j5
.on()
1) Should turn a led on
.off()
✓ Should turn a led off
1 passing (13ms)
1 failing
1) j5 .on() Should turn a led on:
AssertionError: expected undefined to equal 1
at Context.<anonymous> (test/j5.js:9:14)
npm ERR! Test failed. See above for more details.
This is test/j5.js
require('mocha');
var assert = require('chai').assert;
var j5 = require("../j5");
describe('j5', function () {
describe('.on()', function () {
it('Should turn a led on',function(){
var result = j5.on();
assert.equal(result, 1);
});
});
describe('.off()', function () {
it('Should turn a led off', function () {
// var res = j5.on();
// expect(res).to.equal(0);
});
});
});
This is server.js
var express = require("express");
var app = express();
var j5 = require("./j5");
var port = 3000;
app.get('/', function(req, res){
res.send('hello j5');
});
app.get("/on", function(req, res) {
j5.on();
res.send("on");
});
app.get("/off", function(req, res) {
j5.off();
res.send("off");
});
console.log("listening on port http://localhost:" + port);
app.listen(3000);
This is j5.js
var exports = module.exports = {};
var five = require("johnny-five");
var board = new five.Board();
var board_ready = false;
var led = null;
board.on("ready", function() {
board_ready = true;
led = new five.Led(13);
});
exports.on = function() {
if (led !== null && board_ready === true) {
led.on();
return 1;
}
};
exports.off = function() {
if (led !== null && board_ready === true) {
led.off();
return 0;
}
};
EDIT: The path to my j5.js in test/j5.js was wrong. but now I have a new error. AssertionError: expected undefined to equal 1 at Context. (test/j5.js:9:14).
After some playing around I found my error.
johnny-five needs some time to connect to the board via the serial. As soon as the build in REPL is available I can use the functions on() and off(). So I made my test wait for 5 seconds before making the call of j5.on(). The standard max timeout for the done() function is 2000ms. To make this longer I used this.timeout(10000);
This is my new test/j5.js
require('mocha');
var assert = require('chai').assert;
var j5 = require("../j5");
var result = null;
describe('j5', function() {
describe('.on()', function() {
it('Should turn a led on', function(done) {
this.timeout(10000);
setTimeout(function() {
result = j5.on();
assert.equal(result, 1);
done();
}, 5000);
});
});
});
Result of npm test:
> blink#1.0.0 test /Users/icke/Documents/johnny-five/blink
> mocha --reporter spec
1435305595110 Device(s) /dev/cu.usbmodem1421
1435305595124 Connected /dev/cu.usbmodem1421
j5
.on()
1435305598694 Repl Initialized
✓ Should turn a led on (5003ms)
.off()
✓ Should turn a led off
2 passing (5s)

exec 'node app' hangs inside gulp task

This gulp task hangs on exec('node config/app') line. first exec works fine but the second just hangs.
gulp.task('test', function(cb) {
var exec = require('child_process').exec;
exec('echo 3', function(err, stdout) {
console.log(stdout);
});
exec('node config/app', function(err, stdout, stderr) {
console.log(stdout);
var testemOptions = {
file: 'testem.json'
};
var t = new testem();
return t.startCI(testemOptions, function() {
cb();
});
});
});
I can see the output 3 but no output is shown for the second console.log.
I am trying to run my server before running the tests with testem.
I've tried this similar solution but it doesn't work: Exec not returning anything when trying to run git shortlog with nodejs.
Also I've recently asked a hanging testem gulp task question: Testem gulp task hangs after finished.
Edit:
My current solution is:
gulp.task('test', /*['build'],*/ function(cb) {
var spawn = require('child_process').spawn;
var proc = spawn('node', ['config/app']);
proc.stdout.on('readable', function() {
var output = proc.stdout.read();
if (output && output.toString().match('express listening')) {
var testemOptions = {
file: 'testem.json'
};
var t = new testem();
t.startCI(testemOptions, function() {
proc.kill();
cb();
});
}
});
});
If you want to use testem to test the "node config/app" server, you cannot use exec.
Exec is supposed to callback when the command is finished so in your case it will never callback.
try with
gulp.task('test', function(cb) {
var spawn = require('child_process').spawn;
var proc = spawn('node', ['config/app']);
var testStarted = false;
proc.stdout.on('readable', function() {
if (testStarted) return;
testStarted = true;
var testemOptions = {
file: 'testem.json'
};
var t = new testem();
t.startCI(testemOptions, function() {
proc.kill()
cb();
});
}
});
Note that I did not test this code and that it probably does not handle all the corner cases you might encounter (if the server stops unexpectedly for example)
you may also want to check the plugin https://github.com/sargentsurg/gulp-testem
There is ŧestem plugin on github.

Categories