Skip to content

Commit

Permalink
add option n for update command to not save config (#678)
Browse files Browse the repository at this point in the history
* add option d/ delete for update command to delete configuration files during update

* grunt beautification

* rename option to match sysupgrade command

* fixed tests and added noConfigSave tests

* jscs fix

* check options in unit test for not saving config during t2 update
  • Loading branch information
thojansen authored and rwaldron committed Apr 16, 2016
1 parent 83c47d3 commit a8e419e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 12 deletions.
6 changes: 6 additions & 0 deletions bin/tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,12 @@ makeCommand('update')
flag: true,
help: 'Update to the latest version regardless of current version.'
})
.option('n', {
abbr: 'n',
required: false,
flag: true,
help: 'Do not save configuration during update.'
})
.option('openwrt-path', {
abbr: 'op',
required: false,
Expand Down
4 changes: 2 additions & 2 deletions lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ controller.update = function(opts) {

controller.updateWithLocalBuilds = function(opts, tessel) {
return updates.loadLocalBinaries(opts)
.then((images) => tessel.update(images))
.then((images) => tessel.update(opts, images))
.then(() => logs.info('Finished updating Tessel with local builds.'));
};

Expand Down Expand Up @@ -926,7 +926,7 @@ controller.updateTesselWithVersion = function(opts, tessel, currentVersion, buil
return updates.fetchBuild(build)
.then(function startUpdate(image) {
// Update Tessel with it
return tessel.update(image)
return tessel.update(opts, image)
// Log that the update completed
.then(function logCompletion() {
if (!opts.force) {
Expand Down
3 changes: 3 additions & 0 deletions lib/tessel/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ module.exports.callTesselMDNS = function(action) {
module.exports.sysupgrade = function(path) {
return ['sysupgrade', path];
};
module.exports.sysupgradeNoSaveConfig = function(path) {
return ['sysupgrade', '-n', path];
};
module.exports.getMemoryInfo = function() {
return ['cat', '/proc/meminfo'];
};
Expand Down
20 changes: 15 additions & 5 deletions lib/tessel/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ Tessel.prototype.fetchCurrentBuildInfo = function() {
});
};

Tessel.prototype.update = function(newImage) {
Tessel.prototype.update = function(opts, newImage) {
return new Promise((resolve) => {
if (newImage.openwrt.length > 0) {
return this.updateOpenWRT(newImage.openwrt).then(resolve);
return this.updateOpenWRT(opts, newImage.openwrt).then(resolve);
} else {
logs.warn('No OpenWRT binary loaded... skipping OpenWRT update');
resolve();
Expand All @@ -48,7 +48,7 @@ Tessel.prototype.update = function(newImage) {
});
};

Tessel.prototype.updateOpenWRT = function(image) {
Tessel.prototype.updateOpenWRT = function(opts, image) {
// This ensures usb updates will work on older OpenWRT images
// by overwriting the upgrade file
return this.fixOldUpdateScripts()
Expand Down Expand Up @@ -80,8 +80,18 @@ Tessel.prototype.updateOpenWRT = function(image) {
logs.info('Starting OpenWRT update.');
logs.info('Please do not remove power from Tessel.');
logs.info('This process will take at least two minutes...');
// The USBDaemon will cut out or the SSH command will close
this.connection.exec(commands.sysupgrade(updatePath), (err, remoteProc) => {

var sysupgradeCommand = [];
if (opts.n) {
logs.info('Configuration is not saved during update.');
sysupgradeCommand = commands.sysupgradeNoSaveConfig(updatePath);
} else {
logs.info('Configuration is saved during update.');
sysupgradeCommand = commands.sysupgrade(updatePath);
}

// The USBDaemon will cut out or the SSH command will close
this.connection.exec(sysupgradeCommand, (err, remoteProc) => {
if (err) {
return reject(err);
} else {
Expand Down
88 changes: 83 additions & 5 deletions test/unit/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ exports['controller.update'] = {
// The Tessel was updated
test.equal(this.update.callCount, 1);
// The update used the appropriate binaries
test.equal(this.update.calledWith(binaries), true);
test.equal(this.update.calledWith(opts, binaries), true);
// Then the Tessel was closed
test.equal(this.tessel.closed, true);
// We closed all open Tessel connections
Expand Down Expand Up @@ -210,7 +210,7 @@ exports['controller.update'] = {
// Update Tessel was successfully called
test.equal(this.update.callCount, 1);
// It was provided the binaries
test.equal(this.update.calledWith(binaries), true);
test.equal(this.update.calledWith(opts, binaries), true);
// Then Tessel was closed
test.equal(this.tessel.closed, true);
// We closed all open Tessel connections
Expand Down Expand Up @@ -350,7 +350,57 @@ exports['controller.update'] = {
// Update Tessel was not called because it was already up to date
test.equal(this.update.callCount, 1);
// It was provided the binaries
test.equal(this.update.calledWith(binaries), true);
test.equal(this.update.calledWith(opts, binaries), true);
// Then Tessel was closed
test.equal(this.tessel.closed, true);
// We closed all open Tessel connections
test.equal(this.closeTesselConnections.callCount, 1);
// We called the close function with an array
test.equal(Array.isArray(this.closeTesselConnections.args[0]), true);
test.done();
})
.catch(error => {
test.ok(false, `update failed: ${error.toString()}`);
test.done();
});
},

buildLatestNoConfigSave: function(test) {
test.expect(8);

// Create a Tessel sim
this.tessel = TesselSimulator({
type: 'USB',
end: () => Promise.resolve()
});

var binaries = {
firmware: new Buffer(0),
openwrt: new Buffer(0)
};

this.fetchBuild = this.sandbox.stub(updates, 'fetchBuild', function() {
return Promise.resolve(binaries);
});

var opts = {
force: true,
lanPrefer: true,
n: true
};

controller.update(opts)
.then(() => {
// We fetched only one build
test.equal(this.fetchBuild.callCount, 1);
// It was the latest build
test.equal(this.fetchBuild.calledWith(builds[1]), true);
// Update Tessel was not called because it was already up to date
test.equal(this.update.callCount, 1);
// It was provided the binaries and options
test.equal(this.update.calledWith(opts, binaries), true);
// Provided Options match first parameter
test.deepEqual(this.update.lastCall.args[0], opts);
// Then Tessel was closed
test.equal(this.tessel.closed, true);
// We closed all open Tessel connections
Expand Down Expand Up @@ -667,7 +717,7 @@ exports['Tessel.update'] = {
this.openStdinToFile = this.sandbox.stub(commands, 'openStdinToFile');
this.sysupgrade = this.sandbox.stub(commands, 'sysupgrade');

this.tessel.updateOpenWRT(this.newImage.openwrt).then(() => {
this.tessel.updateOpenWRT({}, this.newImage.openwrt).then(() => {
test.equal(this.openStdinToFile.callCount, 1);
test.equal(this.sysupgrade.callCount, 1);
test.equal(this.openStdinToFile.lastCall.args[0], updatePath);
Expand All @@ -679,6 +729,34 @@ exports['Tessel.update'] = {
});
},

configurationShouldNotBeSaved: function(test) {
var updatePath = `/tmp/${updates.OPENWRT_BINARY_FILE}`;

this.exec = this.sandbox.stub(this.tessel.connection, 'exec', (command, handler) => {
handler(null, this.tessel._rps);
setImmediate(() => {
this.tessel._rps.stdout.emit('data', new Buffer('Upgrade completed'));
this.tessel._rps.emit('close');
});
});

this.openStdinToFile = this.sandbox.stub(commands, 'openStdinToFile');
this.sysupgradeNoSaveConfig = this.sandbox.stub(commands, 'sysupgradeNoSaveConfig');

this.tessel.updateOpenWRT({
n: true
}, this.newImage.openwrt).then(() => {
test.equal(this.openStdinToFile.callCount, 1);
test.equal(this.sysupgradeNoSaveConfig.callCount, 1);
test.equal(this.openStdinToFile.lastCall.args[0], updatePath);
test.equal(this.sysupgradeNoSaveConfig.lastCall.args[0], updatePath);
test.done();
}).catch((error) => {
test.ok(false, error);
test.done();
});
},

standardUpdate: function(test) {
// Set the amount of time Tessel waits for the OpenWRT update
// to complete to 1ms so we don't wait forever
Expand Down Expand Up @@ -715,7 +793,7 @@ exports['Tessel.update'] = {
});

// Begin the update
this.tessel.update(this.newImage)
this.tessel.update({}, this.newImage)
// Update completed as expected
.then(() => {
test.equal(this.updateFirmware.callCount, 1);
Expand Down

0 comments on commit a8e419e

Please sign in to comment.