Skip to content

Commit

Permalink
Commands: support memory info request. Fixes gh-388
Browse files Browse the repository at this point in the history
  • Loading branch information
rwaldron committed Oct 21, 2015
1 parent bc9c59f commit b1d46e1
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/tessel/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,6 @@ module.exports.callTesselMDNS = function(action) {
module.exports.sysupgrade = function(path) {
return ['sysupgrade', path];
};
module.exports.getMemoryInfo = function() {
return ['cat', '/proc/meminfo'];
};
84 changes: 84 additions & 0 deletions lib/tessel/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,90 @@ var NODE_PUSH_SCRIPT = __dirname + '/../../resources/start_node_script.sh';
// exporting those definitions for testing.
var actions = {};

var pattern = /(.*):(?:\s+)([0-9]{1,9})/;
var replacements = {
'(anon)': '_anon',
'(file)': '_file',
};

function transformKey(value) {
return Object.keys(replacements).reduce(function(value, key) {
return value.replace(key, replacements[key]);
}, value);
}

/*
Get the results of `cat /proc/meminfo` and create an object with the data.
The produced object will look approximately like the following, where only the
values will vary:
{
MemTotal: 61488000,
MemFree: 28396000,
MemAvailable: 42852000,
Buffers: 4224000,
Cached: 11860000,
SwapCached: 0,
Active: 11200000,
Inactive: 8172000,
Active_anon: 3320000,
Inactive_anon: 52000,
Active_file: 7880000,
Inactive_file: 8120000,
Unevictable: 0,
Mlocked: 0,
SwapTotal: 0,
SwapFree: 0,
Dirty: 0,
Writeback: 0,
AnonPages: 3304000,
Mapped: 5260000,
Shmem: 84000,
Slab: 7480000,
SReclaimable: 1836000,
SUnreclaim: 5644000,
KernelStack: 352000,
PageTables: 388000,
NFS_Unstable: 0,
Bounce: 0,
WritebackTmp: 0,
CommitLimit: 30744000,
Committed_AS: 7696000,
VmallocTotal: 1048372000,
VmallocUsed: 1320000,
VmallocChunk: 1040404000
}
Note that the values are in BYTES!
*/

Tessel.prototype.memoryInfo = function() {
var self = this;
return new Promise(function(resolve, reject) {
return actions.execRemoteCommand(self, 'getMemoryInfo')
.then(function(response) {
if (!response || !response.length) {
return reject('Could not read device memory information.');
}

var meminfo = response.split('\n').reduce(function(result, row) {
var parts = row.match(pattern);
var key, value;

if (parts && parts.length) {
key = transformKey(parts[1]);
value = parseInt(parts[2], 10) * 1000;
result[key] = value;
}
return result;
}, {});

resolve(meminfo);
})
.catch(reject);
});
};
/*
Run a script on a Tessel
param opts: unused so far
Expand Down
109 changes: 109 additions & 0 deletions test/unit/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,121 @@ var mkdirp = require('mkdirp');
var path = require('path');
var rimraf = require('rimraf');
var Ignore = require('fstream-ignore');
var meminfo = fs.readFileSync('test/unit/fixtures/proc-meminfo', 'utf8');
var deployFolder = path.join(__dirname, 'tmp');
var deployFile = path.join(deployFolder, 'app.js');
var codeContents = 'console.log("testing deploy");';
var reference = new Buffer(codeContents);
var sandbox = sinon.sandbox.create();

exports['Tessel.prototype.memoryInfo'] = {
setUp: function(done) {
this.execRemoteCommand = sandbox.stub(deploy, 'execRemoteCommand', function() {
return new Promise(function(resolve) {
resolve(meminfo);
});
});

this.logsWarn = sandbox.stub(logs, 'warn', function() {});
this.logsInfo = sandbox.stub(logs, 'info', function() {});

this.tessel = TesselSimulator();

// This is what the result of processing output from
// `cat /proc/meminfo` must look like.
this.expect = {
MemTotal: 61488000,
MemFree: 28660000,
MemAvailable: 43112000,
Buffers: 4224000,
Cached: 11860000,
SwapCached: 0,
Active: 10936000,
Inactive: 8244000,
Active_anon: 3128000,
Inactive_anon: 52000,
Active_file: 7808000,
Inactive_file: 8192000,
Unevictable: 0,
Mlocked: 0,
SwapTotal: 0,
SwapFree: 0,
Dirty: 0,
Writeback: 0,
AnonPages: 3112000,
Mapped: 5260000,
Shmem: 84000,
Slab: 7460000,
SReclaimable: 1832000,
SUnreclaim: 5628000,
KernelStack: 352000,
PageTables: 348000,
NFS_Unstable: 0,
Bounce: 0,
WritebackTmp: 0,
CommitLimit: 30744000,
Committed_AS: 7072000,
VmallocTotal: 1048372000,
VmallocUsed: 1320000,
VmallocChunk: 1040404000
};

done();
},

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

meminfo: function(test) {
test.expect(4);
this.tessel.memoryInfo().then(function(memory) {
test.equal(this.execRemoteCommand.callCount, 1);
test.equal(this.execRemoteCommand.lastCall.args[0], this.tessel);
test.equal(this.execRemoteCommand.lastCall.args[1], 'getMemoryInfo');
test.deepEqual(memory, this.expect);
test.done();
}.bind(this));
},

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

this.execRemoteCommand.restore();

this.execRemoteCommand = sandbox.stub(deploy, 'execRemoteCommand', function() {
return new Promise(function(resolve) {
resolve();
});
});

this.tessel.memoryInfo().catch(function(error) {
test.equal(error, 'Could not read device memory information.');
test.done();
}.bind(this));
},

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

this.execRemoteCommand.restore();

this.execRemoteCommand = sandbox.stub(deploy, 'execRemoteCommand', function() {
return new Promise(function(resolve) {
resolve('');
});
});

this.tessel.memoryInfo().catch(function(error) {
test.equal(error, 'Could not read device memory information.');
test.done();
}.bind(this));
},

};

exports['Tessel.prototype.deployScript'] = {
setUp: function(done) {
this.deployScript = sandbox.spy(Tessel.prototype, 'deployScript');
Expand Down
34 changes: 34 additions & 0 deletions test/unit/fixtures/proc-meminfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
MemTotal: 61488 kB
MemFree: 28660 kB
MemAvailable: 43112 kB
Buffers: 4224 kB
Cached: 11860 kB
SwapCached: 0 kB
Active: 10936 kB
Inactive: 8244 kB
Active(anon): 3128 kB
Inactive(anon): 52 kB
Active(file): 7808 kB
Inactive(file): 8192 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 3112 kB
Mapped: 5260 kB
Shmem: 84 kB
Slab: 7460 kB
SReclaimable: 1832 kB
SUnreclaim: 5628 kB
KernelStack: 352 kB
PageTables: 348 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 30744 kB
Committed_AS: 7072 kB
VmallocTotal: 1048372 kB
VmallocUsed: 1320 kB
VmallocChunk: 1040404 kB

0 comments on commit b1d46e1

Please sign in to comment.