Skip to content

Commit

Permalink
Merge pull request #205 from rwaldron/usb-error-logging
Browse files Browse the repository at this point in the history
Fix call to undefined logging function in usb_connection.
  • Loading branch information
johnnyman727 committed Jul 18, 2015
2 parents 0481978 + e128f2a commit 8cb8e8a
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 18 deletions.
42 changes: 24 additions & 18 deletions lib/usb_connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ var Daemon = require('./usb/usb_daemon');
var TESSEL_VID = 0x1209;
var TESSEL_PID = 0x7551;

function USBConnection(device) {
var USB = {};

USB.Connection = function(device) {
Duplex.call(this);
this.device = device;
this.connectionType = 'USB';
this.epIn = undefined;
this.epOut = undefined;
}
};

util.inherits(USBConnection, Duplex);
util.inherits(USB.Connection, Duplex);

USBConnection.prototype.exec = function(command, callback) {
USB.Connection.prototype.exec = function(command, callback) {
var self = this;

// Execute the command
Expand All @@ -53,7 +55,7 @@ USBConnection.prototype.exec = function(command, callback) {
});
};

USBConnection.prototype._write = function(chunk, enc, callback) {
USB.Connection.prototype._write = function(chunk, enc, callback) {

if (this.closed) {
callback(new Error('Connection was already closed...'));
Expand All @@ -62,13 +64,13 @@ USBConnection.prototype._write = function(chunk, enc, callback) {
}
};

USBConnection.prototype._read = function() {
USB.Connection.prototype._read = function() {
if (this.closed) {
return this.push(null);
}
};

USBConnection.prototype._receiveMessages = function() {
USB.Connection.prototype._receiveMessages = function() {
var self = this;
// Default transfer size
var transferSize = 4096;
Expand All @@ -85,14 +87,14 @@ USBConnection.prototype._receiveMessages = function() {
return;
} else {
// Otherwise print the error
logs.error('Error reading USB message endpoint:', e);
logs.err('Error reading USB message endpoint:', e);
// Return a non-zero return code
process.exit(-5);
}
});
};

USBConnection.prototype.open = function() {
USB.Connection.prototype.open = function() {
var self = this;
return new Promise(function(resolve, reject) {
// Try to open connection
Expand Down Expand Up @@ -143,7 +145,7 @@ USBConnection.prototype.open = function() {
});
};

USBConnection.prototype.end = function(callback) {
USB.Connection.prototype.end = function(callback) {
var self = this;
// Tell the USB daemon to end all processes active
// on account of this connection
Expand All @@ -155,7 +157,7 @@ USBConnection.prototype.end = function(callback) {
});
};

USBConnection.prototype._close = function(callback) {
USB.Connection.prototype._close = function(callback) {
var self = this;

if (self.closed) {
Expand All @@ -171,7 +173,7 @@ USBConnection.prototype._close = function(callback) {
}.bind(self));
};

USBConnection.prototype._processArgsForTransport = function(command) {
USB.Connection.prototype._processArgsForTransport = function(command) {

if (!Array.isArray(command)) {
return;
Expand All @@ -196,7 +198,7 @@ var scanner;

function startScan() {
if (scanner === undefined) {
scanner = new Scanner();
scanner = new USB.Scanner();

setImmediate(scanner.start.bind(scanner));
}
Expand All @@ -213,11 +215,11 @@ function stopScan() {
return scanner;
}

function Scanner() {}
USB.Scanner = function() {};

util.inherits(Scanner, EventEmitter);
util.inherits(USB.Scanner, EventEmitter);

Scanner.prototype.start = function() {
USB.Scanner.prototype.start = function() {
var self = this;

usb.getDeviceList().forEach(deviceInspector);
Expand All @@ -226,15 +228,19 @@ Scanner.prototype.start = function() {

function deviceInspector(device) {
if ((device.deviceDescriptor.idVendor === TESSEL_VID) && (device.deviceDescriptor.idProduct === TESSEL_PID)) {
var connection = new USBConnection(device);
var connection = new USB.Connection(device);
self.emit('connection', connection);
}
}
};

Scanner.prototype.stop = function() {
USB.Scanner.prototype.stop = function() {
usb.removeAllListeners('attach');
};

module.exports.startScan = startScan;
module.exports.stopScan = stopScan;

if (global.IS_TEST_ENV) {
module.exports.USB = USB;
}
163 changes: 163 additions & 0 deletions test/unit/usb_connection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
var sinon = require('sinon');
var Emitter = require('events').EventEmitter;
var Duplex = require('stream').Duplex;
var USB = require('../../lib/usb_connection').USB;
var Daemon = require('../../lib/usb/usb_daemon');
var logs = require('../../lib/logs');

exports['USB.Connection'] = {
setUp: function(done) {
this.usbConnection = new USB.Connection({});
done();
},

tearDown: function(done) {
done();
},

duplexSubclass: function(test) {
test.expect(1);
test.ok(this.usbConnection instanceof Duplex);
test.done();
},

connectionType: function(test) {
test.expect(1);
test.equal(this.usbConnection.connectionType, 'USB');
test.done();
},
};

exports['USB.Connection.prototype.exec'] = {
setUp: function(done) {
this.sandbox = sinon.sandbox.create();
this.openProcess = this.sandbox.stub(Daemon, 'openProcess');
this.usbConnection = new USB.Connection({});
done();
},

tearDown: function(done) {
this.sandbox.restore();
done();
},

openProcess: function(test) {
test.expect(1);

this.usbConnection.exec(['some -command 1']);

test.equal(this.openProcess.callCount, 1);

// TODO: add more specific tests for handling the opened process
test.done();
},
};

exports['USB.Connection.prototype._write'] = {
setUp: function(done) {
this.sandbox = sinon.sandbox.create();
this.openProcess = this.sandbox.stub(Daemon, 'openProcess');
this.usbConnection = new USB.Connection({});
this.usbConnection.epOut = new Emitter();
this.usbConnection.epOut.transfer = this.sandbox.spy();
done();
},

tearDown: function(done) {
this.sandbox.restore();
done();
},

transfer: function(test) {
test.expect(3);

var spy = this.sandbox.spy();

this.usbConnection._write(1, 2, spy);

test.equal(this.usbConnection.epOut.transfer.callCount, 1);
test.equal(this.usbConnection.epOut.transfer.lastCall.args[0], 1);
test.equal(this.usbConnection.epOut.transfer.lastCall.args[1], spy);

test.done();
},

transferClosed: function(test) {
test.expect(2);

var spy = this.sandbox.spy();

this.usbConnection.closed = true;
this.usbConnection._write(1, 2, spy);

test.equal(this.usbConnection.epOut.transfer.callCount, 0);
test.equal(spy.callCount, 1);

test.done();
},
};

exports['USB.Connection.prototype._receiveMessages'] = {
setUp: function(done) {
this.sandbox = sinon.sandbox.create();
this.err = this.sandbox.stub(logs, 'err');
this.processExit = this.sandbox.stub(process, 'exit');
this.usbConnection = new USB.Connection({});
this.usbConnection.epIn = new Emitter();
this.usbConnection.epIn.startPoll = this.sandbox.spy();
done();
},

tearDown: function(done) {
this.sandbox.restore();
done();
},

startPolling: function(test) {
test.expect(3);

this.usbConnection._receiveMessages();

test.equal(this.usbConnection.epIn.startPoll.callCount, 1);
test.equal(this.usbConnection.epIn.startPoll.lastCall.args[0], 2);
test.equal(this.usbConnection.epIn.startPoll.lastCall.args[1], 4096);
test.done();
},

pushReceivedData: function(test) {
test.expect(1);

this.usbConnection._receiveMessages();

this.usbConnection.epIn.emit('data', new Buffer([0xff, 0xff]));
test.equal(this.usbConnection._readableState.length, 2);
test.done();
},

errorWhenStillOpen: function(test) {
test.expect(2);

this.usbConnection._receiveMessages();

this.usbConnection.epIn.emit('error', 'oh no!');

test.equal(this.err.callCount, 1);
test.equal(this.processExit.callCount, 1);
test.done();
},

errorWhenClosed: function(test) {
test.expect(2);

this.usbConnection._receiveMessages();
this.usbConnection.closed = true;
this.usbConnection.epIn.emit('error', 'oh no!');

// The immediate return prevents these from being
// called from in the error handler
test.equal(this.err.callCount, 0);
test.equal(this.processExit.callCount, 0);
test.done();
},

};

0 comments on commit 8cb8e8a

Please sign in to comment.